/* =========================================================================
   Samaha Law Firm - stylesheet, v2
   Version this filename when the file changes. _headers caches /assets/*
   for a year as immutable, so an edit under the same name will not reach
   anyone who has already loaded the site.

   PALETTE - every value sampled from the supplied business card artwork,
   not chosen. Source of each is stated. Do not revise without saying why.
     #182476  navy      1,014,235 px, the card field itself
     #71C5EA  accent    the rule under the name on the reverse

   NOTE ON PROVENANCE, added after the fact and material:
   the "card" these values were sampled from turned out to be a digital card
   served by a third party QR service, not printed stationery. The wordmark,
   the pointed A and ROOTED IN JUSTICE are his. The navy field may well be that
   service's template default rather than a colour anyone chose. That is why
   the palette moved without the usual objection, and why the old values are
   kept switchable rather than deleted.
     #D4D4D6  paper     158,532 px, the mount the card sits on
   The tagline "ROOTED IN JUSTICE" measures nearer #7EB6EE, a hair more
   violet than the rule. Two near-identical blues is drift, not design, so
   the rule value wins and is used everywhere. One accent, defined once.

   CSS ORDER RULE: every base rule is declared before any max-width media
   query that overrides it. A media query adds no specificity and wins on
   source order alone.
   ========================================================================= */

/* iOS zooms the whole page when a field under 16px takes focus. First rule,
   always. */
input, textarea, select, button { font-size: 16px; }

* { margin: 0; padding: 0; box-sizing: border-box; }

:root {
  /* ==================================================================
     PALETTE, and how to revert it.

     Two palettes live here. The active one is chosen by a single word:
     THEME in tools/content_a.py, which writes data-palette on <html>.

       THEME = "gold"    the current identity
       THEME = "legacy"  the blue and cyan of the scanned card

     Nothing else changes. Rebuild and the whole site swaps. There is no
     second stylesheet to keep in step, which is the usual way a "we can
     always revert" promise quietly stops being true.
     ================================================================== */

  /* --- GOLD, active ------------------------------------------------ */
  --navy: #0B1326;        /* midnight navy */
  --navy-deep: #070C1A;
  --navy-lift: #16203A;
  --accent: #C9A76A;      /* champagne gold */
  --accent-soft: rgba(201, 167, 106, 0.5);
  --page: #F6F4F0;        /* ivory */
  --ink: #1B1D2E;
  --muted: #5A6072;       /* slate */
  --muted-on-navy: #A8B0C4;
  --border: #E3DFD6;
  --border-on-navy: rgba(201, 167, 106, 0.26);
  --btn-hover-text: #0B1326;
  --paper: #D4D4D6;

  --wrap: 1120px;
  --gap: clamp(18px, 4vw, 40px);
  --sans: "Jost", "Century Gothic", "Futura", system-ui, sans-serif;
  --serif: "Source Serif 4", "Georgia", "Times New Roman", serif;
  --arabic: "IBM Plex Sans Arabic", "Segoe UI", Tahoma, sans-serif;
}

/* --- LEGACY, the scanned card's blue and cyan ----------------------- */
html[data-palette="legacy"] {
  --navy: #182476;
  --navy-deep: #101a4a;
  --navy-lift: #1e2c8c;
  --accent: #71C5EA;
  --accent-soft: rgba(113, 197, 234, 0.5);
  --page: #F6F4F0;
  --ink: #1B1D2E;
  --muted: #565B70;
  --muted-on-navy: #b9c2e8;
  --border: #E3DFD6;
  --border-on-navy: rgba(113, 197, 234, 0.28);
  --btn-hover-text: #182476;
}

html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }

body {
  font-family: var(--serif);
  font-size: 1.0625rem;
  line-height: 1.65;
  color: var(--ink);
  background: var(--page);
  -webkit-font-smoothing: antialiased;
}

/* Arabic swaps direction and the whole type stack. Set on <html> by app.js. */
html[dir="rtl"] body { font-family: var(--arabic); line-height: 1.9; }
html[dir="rtl"] h1, html[dir="rtl"] h2, html[dir="rtl"] h3,
html[dir="rtl"] .eyebrow, html[dir="rtl"] .btn, html[dir="rtl"] nav a {
  font-family: var(--arabic);
  letter-spacing: 0;
}

img { max-width: 100%; display: block; }
a { color: inherit; }
.grid > * { min-width: 0; }

h1, h2, h3, .eyebrow, .btn, nav a, .stat-num {
  font-family: var(--sans);
  font-weight: 300;
}

h1 { font-size: clamp(2.1rem, 6vw, 3.6rem); line-height: 1.08; letter-spacing: 0.005em; }
h2 { font-size: clamp(1.55rem, 3.6vw, 2.3rem); line-height: 1.18; }
h3 { font-size: 1.2rem; line-height: 1.3; font-weight: 400; }

.eyebrow {
  font-size: 0.72rem;
  letter-spacing: 0.34em;
  text-transform: uppercase;
  color: var(--accent);
  font-weight: 400;
}
.eyebrow-dark { color: var(--navy); }

/* His motto, from the card, at the top of the home page and nowhere else
   above the fold. Given the card's own treatment: wide tracking, accent, a
   rule beneath, and room to breathe. Deliberately NOT in the sticky header:
   a motto repeated above every scroll on thirteen pages stops being read. */
.motto {
  font-family: var(--sans); font-weight: 300;
  font-size: clamp(0.82rem, 1.5vw, 1.02rem);
  letter-spacing: 0.44em; text-transform: uppercase;
  color: var(--accent);
  margin-bottom: clamp(28px, 5vw, 52px);
  position: relative; padding-bottom: 22px;
}
html[dir="rtl"] .motto { letter-spacing: 0; font-family: var(--arabic); }
.motto::after {
  content: ""; position: absolute; bottom: 0; inset-inline-start: 0;
  width: 56px; height: 1px; background: var(--accent-soft);
}
.hero-motto h1 { max-width: 19ch; }

.wrap { max-width: var(--wrap); margin: 0 auto; padding: 0 var(--gap); }
/* More air. Elite practices are recognisable by whitespace before they
   are recognisable by anything else. */
.section { padding: clamp(68px, 11vw, 132px) 0; }
.section-navy { background: var(--navy); color: #fff; }
.section-navy .lead, .section-navy p { color: #e7ebff; }
.lead { font-size: clamp(1.08rem, 2.2vw, 1.32rem); line-height: 1.6; color: var(--muted); }

.rule {
  height: 4px;
  background: var(--accent);
  border: 0;
  width: 100%;
  max-width: 640px;
  margin: 22px 0 0;
}

/* --------------------------------------------------------------------- */
/* Skip link and header                                                   */
/* --------------------------------------------------------------------- */
/* The skip link must be off-screen without being off-canvas. The usual
   left:-9999px trick is safe in LTR, where left overflow does not scroll,
   and wrong in RTL, where it does: it added 9,999px of scrollable width to
   every Arabic page and nothing looked broken. Clip to a 1px box instead,
   which occupies no layout in either direction. */
.skip {
  position: absolute; top: 0; inset-inline-start: 0; z-index: 1000;
  width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
  background: var(--accent); color: var(--btn-hover-text);
  padding: 12px 18px; font-family: var(--sans);
}
.skip:focus {
  width: auto; height: auto; overflow: visible;
  clip: auto; clip-path: none;
  top: 8px; inset-inline-start: 8px;
}

header.site {
  position: sticky; top: 0; z-index: 800;
  background: var(--navy);
  border-bottom: 1px solid var(--border-on-navy);
}
.bar {
  /* The bar has its OWN width, wider than the content column. It was capped
     at --wrap (1120px), which is why the English header needed 1136px and the
     French one 1293px and BOTH wrapped to a second row at every screen size.
     Arabic fitted only because its labels are shorter, which is why the bug
     looked like an English-only problem. */
  max-width: 1400px; margin: 0 auto; padding: 14px var(--gap);
  /* Three columns: brand, centred navigation, language.
     1fr auto 1fr, not auto 1fr auto. With auto side tracks the middle one is
     pushed by the difference between them, and the brand is 203px wide while
     the language switch is 134px, so the nav sat 34px off centre at every
     width. Equal side tracks put the navigation on the true centre line
     regardless of how long the brand or the switch happen to be. */
  display: grid; grid-template-columns: 1fr auto 1fr;
  align-items: center; gap: 20px;
}
/* The brand is now the drawn lockup, inline SVG inheriting currentColor so
   one file serves the navy header and the navy footer alike. */
.brand { display: block; text-decoration: none; color: #fff; line-height: 0; }
/* Stroke width in SCREEN pixels, not drawing units, via
   vector-effect="non-scaling-stroke" on the paths. At 38px the proportional
   stroke came out at 0.89 device pixels on a standard display: under one, so
   it could not be painted as a line and rendered grey. These values are chosen
   to sit just above 1 device pixel at 1x and stay light at 2x. */
.wordmark { height: 38px; width: auto; display: block; }
.wordmark .wm-main { stroke-width: 1.15px; }
.wordmark .wm-sub path { stroke-width: 1px; }
/* The second line takes the accent, the way the old text subtitle did. Styled
   here rather than baked into the SVG so it follows the theme: THEME="legacy"
   turns it cyan with everything else. Gold on midnight navy is 8.12:1. */
.wordmark .wm-sub { stroke: var(--accent); }
.foot-brand { display: block; color: #fff; line-height: 0; }
.foot-brand .wordmark { height: 44px; }
/* Slightly heavier at the larger footer size, so the two lockups read as the
   same weight rather than the same number. */
.foot-brand .wordmark .wm-main { stroke-width: 1.3px; }
.foot-brand .wordmark .wm-sub path { stroke-width: 1.1px; }
nav.primary { display: flex; align-items: center;
  gap: 15px; flex-wrap: wrap; justify-content: center; }
nav.primary a {
  color: #dfe4ff; text-decoration: none; font-size: 0.71rem; white-space: nowrap;
  letter-spacing: 0.16em; text-transform: uppercase; padding: 8px 0;
  border-bottom: 2px solid transparent;
}
/* :not(.back-link) matters. The back link is an <a> inside nav.primary, so
   it inherited the navigation's underline-on-hover and drew a second rule
   under itself, on top of the short dash it already carries as its own
   indicator. Two hover affordances on one control. */
nav.primary a:not(.back-link):hover,
nav.primary a:not(.back-link):focus-visible { color: #fff; border-bottom-color: var(--accent); }
nav.primary a.back-link { border-bottom: 0; }
.brand { justify-self: start; }
.lang-switch { justify-self: end; }
nav.primary a[aria-current="page"] { color: #fff; border-bottom-color: var(--accent); }

/* Three languages cannot be a toggle. A cycling button hides French from
   anyone who does not press twice, so all three states are always visible. */
.lang-switch {
  display: inline-flex; border: 1px solid var(--border-on-navy); flex-shrink: 0;
}
.lang-switch button {
  background: transparent; border: 0; cursor: pointer;
  color: var(--muted-on-navy); font-family: var(--sans);
  font-size: 0.72rem; letter-spacing: 0.12em; text-transform: uppercase;
  padding: 0 11px; min-height: 42px; min-width: 44px;
}
.lang-switch button + button { border-inline-start: 1px solid var(--border-on-navy); }
.lang-switch button[aria-pressed="true"] { background: var(--accent); color: var(--btn-hover-text); }
.lang-switch button:hover[aria-pressed="false"] { background: color-mix(in srgb, var(--accent) 14%, transparent); color: #fff; }
.lang-switch button:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.menu-btn { display: none; }

/* --------------------------------------------------------------------- */
/* Hero                                                                   */
/* --------------------------------------------------------------------- */
.hero {
  background: var(--navy);
  color: #fff;
  padding: clamp(56px, 11vw, 128px) 0 clamp(48px, 8vw, 96px);
  position: relative;
  overflow: hidden;
}
.hero::after {
  content: ""; position: absolute; inset-inline-end: -14%; top: -28%;
  width: 62vw; height: 62vw; max-width: 760px; max-height: 760px;
  border: 1px solid color-mix(in srgb, var(--accent) 16%, transparent); border-radius: 50%;
  pointer-events: none;
}
.hero h1 { max-width: 17ch; }
.hero .lead { color: #ccd4ff; max-width: 56ch; margin-top: 24px; }
.hero-actions { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 38px; }

/* RESTRAINT PASS.
   The accent was filling every primary button, which reads as software rather
   than counsel. On the business card that colour appears exactly twice: one
   hairline rule and one line of type. The site now honours that ratio. The
   accent is punctuation, not surface: rules, hovers, small marks. Primary
   buttons carry contrast instead of colour. */
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 50px; padding: 14px 30px;
  letter-spacing: 0.16em; text-transform: uppercase; font-size: 0.76rem;
  text-decoration: none; border: 1px solid transparent; cursor: pointer;
  background: #fff; color: var(--navy);
  transition: background .2s, color .2s, border-color .2s;
}
.btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.btn-ghost { background: transparent; color: #fff; border-color: rgba(255,255,255,.34); }
.btn-solid-navy { background: var(--navy); color: #fff; }

/* HOVER STATES, and two bugs they carried.
   1. .btn-solid-navy:hover set only a background. The colour fell through to
      .btn:hover, which is --btn-hover-text, i.e. navy. Navy text on
      navy-lift: the "Save to my contacts" button went unreadable. Every
      hover rule now sets BOTH properties, so a variant can never inherit
      half a state.
   2. On a touch screen :hover sticks after a tap and does not clear until
      something else is tapped, which is why the button stayed dark after it
      was pressed rather than flashing. Gating on (hover: hover) means a
      phone never enters a hover state at all. */
@media (hover: hover) and (pointer: fine) {
  .btn:hover { background: var(--accent); color: var(--btn-hover-text); }
  .btn-ghost:hover { background: transparent; border-color: var(--accent); color: var(--accent); }
  .btn-solid-navy:hover { background: var(--navy-lift); color: #fff; }
}
/* Touch gets a pressed state instead, which ends when the finger lifts. */
.btn:active { background: var(--accent); color: var(--btn-hover-text); }
.btn-ghost:active { background: transparent; border-color: var(--accent); color: var(--accent); }
.btn-solid-navy:active { background: var(--navy-lift); color: #fff; }

/* --------------------------------------------------------------------- */
/* Credential strip                                                       */
/* --------------------------------------------------------------------- */
/* Credentials were a second navy band directly under a navy hero: two dark
   blocks stacked, which is most of where "too much blue" came from. They are
   now restrained cards on ivory, each with a category label above the
   credential, so they read as proof points rather than as statistics. */
.creds { background: var(--page); padding: clamp(52px, 8vw, 84px) 0; }
.creds .grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 22px; }
.cred {
  background: #FFFDFA; border: 1px solid var(--border);
  padding: 28px 24px 26px; position: relative;
}
.cred::before {
  content: ""; position: absolute; top: 0; inset-inline-start: 0;
  width: 42px; height: 2px; background: var(--accent);
}
.cred .cred-label {
  display: block; font-family: var(--sans); font-size: 0.62rem;
  letter-spacing: 0.26em; text-transform: uppercase;
  color: var(--muted); margin-bottom: 10px;
}
html[dir="rtl"] .cred .cred-label { letter-spacing: 0; font-family: var(--arabic); }
.cred .stat-num { display: block; font-size: 1.5rem; color: var(--navy); line-height: 1.2; }
.cred p { font-size: 0.88rem; color: var(--muted); margin-top: 8px; line-height: 1.5; }

/* --------------------------------------------------------------------- */
/* Two readings - the signature control                                   */
/* --------------------------------------------------------------------- */
.readings-head { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 24px; justify-content: space-between; }

.reading-switch {
  display: inline-flex; border: 1px solid var(--border);
  background: #FFFDFA; padding: 4px;
}
.reading-switch button {
  border: 0; background: transparent; cursor: pointer;
  font-family: var(--sans); font-size: 0.78rem; letter-spacing: 0.13em;
  text-transform: uppercase; padding: 12px 18px; min-height: 44px;
  color: var(--muted);
}
.reading-switch button[aria-pressed="true"] { background: var(--navy); color: #fff; }
.reading-switch button:focus-visible { outline: 2px solid var(--navy); outline-offset: 2px; }
.section-navy .reading-switch { border-color: var(--border-on-navy); background: transparent; }
.section-navy .reading-switch button { color: var(--muted-on-navy); }
.section-navy .reading-switch button[aria-pressed="true"] { background: var(--accent); color: var(--btn-hover-text); }

.cards { display: grid; grid-template-columns: repeat(3, 1fr); gap: 26px; margin-top: 52px; }
.card {
  background: #FFFDFA; border: 1px solid var(--border);
  padding: 38px 32px 34px;
  display: flex; flex-direction: column;
}
/* A short rule above the heading instead of a 3px bar across the whole card.
   Six cards each capped in accent turned the grid into a chart. */
.card h3 { margin-bottom: 16px; color: var(--navy); padding-top: 18px; position: relative; }
.card h3::before {
  content: ""; position: absolute; top: 0; inset-inline-start: 0;
  width: 28px; height: 2px; background: var(--accent);
}
.card p { color: var(--muted); font-size: 1rem; }
.card .reading { display: none; }
.card .reading.is-on { display: block; }

.reading-note {
  margin-top: 34px; font-size: 0.94rem; color: var(--muted);
  border-inline-start: 3px solid var(--accent); padding-inline-start: 16px; max-width: 68ch;
}

/* --------------------------------------------------------------------- */
/* Split, profile, lists                                                  */
/* --------------------------------------------------------------------- */
.split { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(28px, 6vw, 72px); align-items: start; }
.split-narrow { grid-template-columns: 0.8fr 1.2fr; }

/* Silent portrait aperture. No text: a visitor does not need to be told the
   site is unfinished. Composed so it reads as a design element until the
   photograph lands, at which point the image replaces the svg. */
.portrait-slot {
  aspect-ratio: 4 / 5;
  background:
    radial-gradient(120% 90% at 30% 15%, #1e2c8c 0%, var(--navy) 45%, #101a4a 100%);
  border: 1px solid var(--border);
  display: flex; align-items: center; justify-content: center;
  overflow: hidden; position: relative;
}
.portrait-slot::after {
  content: ""; position: absolute; inset: 14px;
  border: 1px solid color-mix(in srgb, var(--accent) 22%, transparent);
  pointer-events: none;
}
.portrait-watermark { width: 46%; height: auto; opacity: 0.13; }
.portrait-watermark path { fill: none; stroke: #fff; stroke-width: 2.6; }
.portrait-slot img { width: 100%; height: 100%; object-fit: cover; }

ul.ticks { list-style: none; margin-top: 22px; }
ul.ticks li {
  position: relative; padding-inline-start: 26px; margin-bottom: 14px;
  color: var(--muted);
}
ul.ticks li::before {
  content: ""; position: absolute; inset-inline-start: 0; top: 0.72em;
  width: 12px; height: 2px; background: var(--accent);
}
.section-navy ul.ticks li { color: #dfe4ff; }

.timeline { list-style: none; margin-top: 30px; border-inline-start: 1px solid var(--border); }
.timeline li { padding: 0 0 26px 26px; position: relative; }
html[dir="rtl"] .timeline li { padding: 0 26px 26px 0; }
.timeline li::before {
  content: ""; position: absolute; inset-inline-start: -5px; top: 8px;
  width: 9px; height: 9px; background: var(--accent); border-radius: 50%;
}
.timeline h3 { color: var(--navy); font-size: 1.05rem; }
.timeline p { color: var(--muted); font-size: 0.96rem; }

/* --------------------------------------------------------------------- */
/* Contact                                                                */
/* --------------------------------------------------------------------- */
.contact-grid { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(28px, 6vw, 64px); }
.contact-list { list-style: none; }
.contact-list li { padding: 18px 0; border-bottom: 1px solid var(--border-on-navy); }
.contact-list .label {
  display: block; font-family: var(--sans); font-size: 0.7rem;
  letter-spacing: 0.24em; text-transform: uppercase; color: var(--accent); margin-bottom: 6px;
}
.contact-list a { color: #fff; text-decoration: none; border-bottom: 1px solid transparent; word-break: break-word; }
.contact-list a:hover { border-bottom-color: var(--accent); }

form.enquiry { display: grid; gap: 16px; }
form.enquiry label {
  font-family: var(--sans); font-size: 0.72rem; letter-spacing: 0.2em;
  text-transform: uppercase; color: var(--accent); display: block; margin-bottom: 7px;
}
form.enquiry input, form.enquiry textarea, form.enquiry select {
  width: 100%; padding: 13px 14px; background: rgba(255, 255, 255, 0.06);
  border: 1px solid var(--border-on-navy); color: #fff;
  font-family: var(--serif);
}
html[dir="rtl"] form.enquiry input,
html[dir="rtl"] form.enquiry textarea,
html[dir="rtl"] form.enquiry select { font-family: var(--arabic); }
form.enquiry input:focus, form.enquiry textarea:focus, form.enquiry select:focus {
  outline: 2px solid var(--accent); outline-offset: 1px;
}
form.enquiry textarea { min-height: 132px; resize: vertical; }
.form-note { font-size: 0.85rem; color: var(--muted-on-navy); }

/* --------------------------------------------------------------------- */
/* Footer                                                                 */
/* --------------------------------------------------------------------- */
/* Compacted. It had grown into a page: four columns, a three line
   disclaimer and a bulleted legal list. Now three tight columns, a one
   line disclaimer linking to the full notice, and the legal links in the
   base rule. */
footer.site { background: var(--navy-deep); color: #fff; padding: 44px 0 22px; font-size: 0.84rem; }
.foot-grid { display: grid; grid-template-columns: 1.3fr 1fr 1.1fr; gap: 30px 40px; }
footer.site h3 {
  font-size: 0.62rem; letter-spacing: 0.24em; text-transform: uppercase;
  color: var(--muted-on-navy); margin-bottom: 12px;
}
footer.site ul { list-style: none; }
footer.site li { margin-bottom: 6px; }
/* ONE underline mechanism in the footer, not two. Previously links carried
   text-decoration:underline on hover AND a border-bottom from .disclaimer or
   .studio, which drew two rules a pixel apart. text-underline-offset also
   puts the rule where a serif at this size actually wants it, clear of the
   descenders, instead of touching the baseline. */
footer.site a {
  color: #d5dbff; font-size: 0.82rem;
  text-decoration: underline;
  text-decoration-color: transparent;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.32em;
  transition: color .2s, text-decoration-color .2s;
}
footer.site a:hover, footer.site a:focus-visible {
  color: #fff; text-decoration-color: var(--accent);
}
.foot-tag {
  font-family: var(--sans); letter-spacing: 0.3em; text-transform: uppercase;
  color: var(--accent); font-size: 0.66rem; margin-top: 10px;
}
html[dir="rtl"] .foot-tag { letter-spacing: 0; }
/* Three cells: location, studio credit, copyright. Grid rather than
   space-between, because with three flex children the middle one drifts off
   centre as soon as the outer two differ in width, and they always do once
   the language changes. justify-self uses logical values, so the row mirrors
   itself in Arabic with no separate rule. */
.foot-base {
  margin-top: 30px; padding-top: 18px; border-top: 1px solid var(--border-on-navy);
  display: grid; grid-template-columns: 1fr auto 1fr; gap: 12px 20px;
  align-items: center;
  font-size: 0.78rem; color: var(--muted-on-navy);
}
.foot-base > :first-child { justify-self: start; }
.foot-base > :last-child { justify-self: end; }
.foot-credit { justify-self: center; text-align: center; }
.foot-credit span, .foot-credit a { font-family: var(--sans); letter-spacing: 0.06em; color: var(--accent); }
/* The studio credit is a link, so it needs a hover and a focus ring like any
   other. The underline is on the accent rule colour rather than the text, so
   it reads as part of the palette instead of a default browser link. */
.foot-credit a.studio:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.disclaimer { max-width: 44ch; font-size: 0.76rem; color: var(--muted-on-navy); margin-top: 16px; }
/* .disclaimer no longer contains a link. The base rule carries Disclaimer
   one line below, and two routes to the same page is clutter. */

/* 404 */
.oops { min-height: 68vh; display: flex; align-items: center; background: var(--navy); color: #fff; }

/* --------------------------------------------------------------------- */
/* v2 components: prose, plain cards, empty states, legal, map, CTA band   */
/* Declared here, before the media queries, per the CSS order rule.        */
/* --------------------------------------------------------------------- */

.prose { max-width: 68ch; }
.prose p + p { margin-top: 1.1em; }
.section-navy .prose p { color: #dfe4ff; }

.plaincards { display: grid; grid-template-columns: repeat(3, 1fr); gap: 26px; margin-top: 52px; }
.plaincard {
  background: #FFFDFA; border: 1px solid var(--border);
  padding: 36px 32px 32px;
}
.plaincard h3 { color: var(--navy); margin-bottom: 14px; padding-top: 18px; position: relative; }
.plaincard h3::before {
  content: ""; position: absolute; top: 0; inset-inline-start: 0;
  width: 28px; height: 2px; background: var(--accent);
}
.plaincard p { color: var(--muted); font-size: 1rem; }
.plaincard a.more {
  display: inline-block; margin-top: 16px; font-family: var(--sans);
  font-size: 0.74rem; letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--navy); text-decoration: none;
  border-bottom: 2px solid var(--accent); padding-bottom: 3px;
}
.plaincard a.more:hover { color: var(--navy-lift); }
.section-navy .plaincard { background: rgba(255,255,255,.04); border-color: var(--border-on-navy); }
.section-navy .plaincard h3 { color: #fff; }
.section-navy .plaincard p { color: var(--muted-on-navy); }

/* Empty state. Used where a section is built but has no content yet. It is
   deliberately visible rather than hidden: a law firm that pads an empty
   page with filler is telling a prospective client how it drafts. */
.empty {
  border: 1px dashed var(--border-on-navy);
  padding: clamp(30px, 6vw, 56px);
  max-width: 74ch;
}
.empty h2 { margin-bottom: 16px; }
.empty p { color: #dfe4ff; }
.empty p + p { margin-top: 1em; }
.empty .mark { width: 26px; height: 26px; display: block; margin-bottom: 20px; }
.empty .mark path { fill: none; stroke: var(--accent); stroke-width: 4.2; }

/* The A from the wordmark, reused as a section marker. Same shape as the
   favicon, so the identity carries through at every scale. */
.sectionmark { width: 20px; height: 20px; display: block; margin-bottom: 18px; }
.sectionmark path { fill: none; stroke: var(--accent); stroke-width: 4.6; }

.legal-body { max-width: 72ch; }
.legal-body section { margin-top: 40px; }
.legal-body h2 {
  font-size: 1.22rem; color: var(--navy);
  padding-bottom: 12px; border-bottom: 1px solid var(--border);
}
.legal-body p { margin-top: 16px; color: var(--muted); }
.legal-meta {
  margin-top: 48px; padding-top: 20px; border-top: 1px solid var(--border);
  font-family: var(--sans); font-size: 0.78rem; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--muted);
}

.notice {
  border-inline-start: 3px solid var(--accent);
  padding: 4px 0 4px 18px; margin-top: 34px;
  max-width: 72ch; color: var(--muted); font-size: 0.95rem;
}
html[dir="rtl"] .notice { padding: 4px 18px 4px 0; }
.section-navy .notice { color: var(--muted-on-navy); }

.map-slot {
  margin-top: 26px; border: 1px dashed var(--border-on-navy);
  padding: 30px; color: var(--muted-on-navy); font-size: 0.92rem;
}

.cta-band { background: var(--navy); color: #fff; text-align: center; }
.cta-band .wrap { max-width: 720px; }
.cta-band .lead { color: #ccd4ff; margin: 20px auto 0; }
.cta-band .hero-actions { justify-content: center; }
.cta-band hr.rule { margin: 22px auto 0; max-width: 220px; }

.pagehead-sub {
  font-family: var(--sans); font-size: 0.74rem; letter-spacing: 0.2em;
  text-transform: uppercase; color: var(--accent); margin-top: 26px;
}

/* --------------------------------------------------------------------- */
/* Floating stack                                                         */
/*                                                                        */
/* They rise together above the footer rather than sitting on top of it,   */
/* and they hide together when the mobile menu opens.                      */
/*                                                                        */
/* WhatsApp is NOT its brand green here. That is a deliberate departure    */
/* from WhatsApp's own brand guidance, made because a green disc on a navy */
/* page is the one element that reads as bolted on. The tradeoff is real:  */
/* the green is instantly recognised and recolouring costs some of that    */
/* recognition, which is why the glyph itself is left completely intact.   */
/* --------------------------------------------------------------------- */
.float-stack {
  position: fixed; inset-inline-end: 20px; z-index: 900;
  display: flex; flex-direction: column-reverse; gap: 12px;
  /* No lift any more: the stack hides at the footer instead, so this is a
     constant rather than a value JavaScript keeps writing. */
  bottom: 28px;
  transition: opacity .2s, transform .2s, visibility 0s linear .2s;
}
/* The word now sits INSIDE the disc, under the mark, rather than in a pill
   hanging beneath it. Two consequences worth recording:
     - it no longer floats over the ivory sections, so the 2.07:1 gold on
       ivory problem disappears by construction rather than by patching. Gold
       on midnight navy is 8.12:1.
     - it costs the mark some height. The scales drop from 28px to 21px to
       leave room, which is the honest price of the tidier shape. */
.float-item { display: flex; flex-direction: column; align-items: center; }
.btn-label {
  font-family: var(--sans); font-size: 8.5px; line-height: 1;
  letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--accent); margin-top: 2px;
  /* 8.5px is small. It is legible because it is short, tracked, uppercase and
     at 8.12:1, and because it is decoration: the button's aria-label carries
     the real name, so nothing depends on reading this. */
}
html[dir="rtl"] .btn-label { letter-spacing: 0; font-family: var(--arabic); font-size: 9px; }

.float-btn {
  width: 52px; height: 52px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  border: 1px solid var(--border-on-navy); cursor: pointer; text-decoration: none;
  box-shadow: 0 4px 16px rgba(16, 26, 86, .28);
  transition: opacity .2s, transform .2s, background .2s, border-color .2s;
}
.float-btn svg { width: 24px; height: 24px; }
.float-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

/* visibility, not opacity alone. An opacity:0 button stays in the tab order,
   so keyboard users land on an invisible control and cannot tell where focus
   went. visibility:hidden removes it from the tab order; the delayed
   transition keeps the fade. */
.float-hidden {
  opacity: 0; pointer-events: none; transform: scale(.85);
  visibility: hidden;
}
.float-btn { transition: opacity .2s, transform .2s, background .2s, border-color .2s, visibility 0s linear .2s; }
.float-btn:not(.float-hidden) { transition-delay: 0s; }

/* Back to top: the balance, resting on the pointed A from the wordmark. */
/* Scroll progress ring. The perimeter fills as the page is read, so the
   control reports where you are as well as offering to take you back. The
   ring is drawn with conic-gradient on a pseudo element rather than a second
   SVG, so it costs no markup and no request. */
#backTop { background: var(--navy); position: relative; }
#backTop:hover { background: var(--navy-lift); border-color: var(--accent); }
#backTop::before {
  content: ""; position: absolute; inset: -3px; border-radius: 50%;
  background: conic-gradient(var(--accent) calc(var(--progress, 0) * 1turn),
                             color-mix(in srgb, var(--accent) 16%, transparent) 0);
  z-index: -1;
}
#backTop::after {
  content: ""; position: absolute; inset: -1px; border-radius: 50%;
  background: var(--navy); z-index: -1;
}
#backTop:hover::after { background: var(--navy-lift); }
@supports not (background: conic-gradient(red 0turn, blue 0)) {
  #backTop::before { background: color-mix(in srgb, var(--accent) 16%, transparent); }
}
/* The scales share the disc with the word now, so they give up some height:
   21 of 52 rather than 28. The monogram is the identity mark and stays on
   the favicon, watermark and share image; a control should say what it does
   rather than repeat the logo. */
#backTop { flex-direction: column; gap: 0; padding-top: 2px; }
#backTop svg { width: 21px; height: 21px; fill: none;
  stroke-linecap: round; stroke-linejoin: round; }
#backTop .beam, #backTop .stem, #backTop .base {
  stroke: var(--accent); stroke-width: 1.6;
}
#backTop .pan { fill: none; stroke: var(--accent); stroke-width: 1.4; }
/* The apex is solid. It is the wordmark letterform and the arrowhead at the
   same time, and an outline at this size loses both readings. */
#backTop .apex { fill: #fff; stroke: none; }
/* The alternative mark, selected by BACK_TOP_MARK in tools/content_a.py. */
#backTop .mono-mark { width: 24px; height: 24px; }
#backTop .mono-mark path {
  fill: none; stroke: #fff; stroke-width: 4.4; stroke-linecap: butt;
  transition: stroke .2s;
}
#backTop:hover .mono-mark path { stroke: var(--accent); }

#waFloat { background: var(--accent); color: var(--btn-hover-text); }
#waFloat:hover { background: color-mix(in srgb, var(--accent) 78%, #fff); }
#waFloat svg { fill: currentColor; stroke: none; }

@media (prefers-reduced-motion: reduce) {
  .float-stack, .float-btn { transition: none; }
}

/* --------------------------------------------------------------------- */
/* Contact icons, footer contact list, footer legal row                    */
/*                                                                        */
/* Icons sit BESIDE the number and the address, never instead of them.     */
/* Replacing the text to hide it from crawlers would break tap to call,    */
/* hide the details from screen readers, and break the name, address and   */
/* phone consistency local search ranking depends on. See the note above   */
/* ICONS in tools/build.py.                                                */
/* --------------------------------------------------------------------- */
.ic {
  /* The SVG also carries width, height, fill and stroke as attributes, so a
     stylesheet that fails to load degrades to a small correct icon rather
     than a full width black shape. These rules refine, they do not rescue. */
  width: 15px; height: 15px; flex: 0 0 15px; color: var(--accent);
  fill: none; stroke: var(--accent); stroke-width: 1.5;
  stroke-linecap: round; stroke-linejoin: round;
  /* Optical alignment: an icon centred on the line box sits high next to
     text with a large x-height. */
  margin-top: 0.2em;
}
.foot-contact li { display: flex; align-items: flex-start; gap: 10px; }
.foot-contact span { color: #d5dbff; font-size: 0.82rem; }
.contact-line { display: flex; align-items: flex-start; gap: 11px; }
.contact-line .ic { width: 17px; height: 17px; flex-basis: 17px; }

.foot-legal { display: flex; flex-wrap: wrap; gap: 6px 18px; }
.foot-legal a { font-size: 0.78rem; }

/* --------------------------------------------------------------------- */
/* Legal notices: minimal chrome                                          */
/*                                                                        */
/* Someone reading a privacy notice is checking one fact, not browsing a   */
/* practice. Full navigation there is an invitation to wander off          */
/* mid-sentence. They get the wordmark, one way back, and the language     */
/* switch, which is not optional on a trilingual site.                     */
/* --------------------------------------------------------------------- */
.header-minimal { position: static; }
/* Same 14px as every other page. It was 20px, which made the bar 84px against
   72px elsewhere and dropped the logo 6px on the notices and the card. Small
   enough to look like a rendering accident and consistent enough to look
   deliberate, which is the worst combination. */
.header-minimal .bar { padding-top: 14px; padding-bottom: 14px; }
.back-link {
  color: #dfe4ff; text-decoration: none;
  font-family: var(--sans); font-size: 0.74rem;
  letter-spacing: 0.16em; text-transform: uppercase;
  display: inline-flex; align-items: center; gap: 10px;
  min-height: 44px;
}
.back-link::before {
  content: ""; width: 22px; height: 1px; background: var(--accent);
  transition: width .2s;
}
.back-link:hover { color: #fff; }
.back-link:hover::before { width: 32px; }
.back-link:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
html[dir="rtl"] .back-link { letter-spacing: 0; font-family: var(--arabic); }

.footer-minimal { padding-top: 26px; }
.footer-minimal .foot-base { margin-top: 0; }

/* --------------------------------------------------------------------- */
/* The digital card                                                       */
/*                                                                        */
/* Held up to another person, at arm's length, often in poor light. The    */
/* code therefore sits on white with generous quiet space around it, not   */
/* on the navy: a dark ground under a QR is the commonest reason a scan    */
/* fails, because phone cameras expect dark modules on light.              */
/* --------------------------------------------------------------------- */
.card-section { padding-top: clamp(40px, 6vw, 64px); }
.card-wrap { display: grid; grid-template-columns: auto 1fr; gap: clamp(28px, 5vw, 64px); align-items: start; }
.card-qr {
  background: #fff; padding: 22px; border: 1px solid var(--border);
  line-height: 0;
}
.card-qr img { width: 320px; height: 320px; display: block; }
.card-body .lead { max-width: 46ch; }
.card-line {
  font-family: var(--sans); font-size: 1.02rem; color: var(--ink);
  margin-top: 8px;
}
.card-line:first-of-type { margin-top: 26px; }
/* .form-note is written for the navy contact panel. On the card it sits on
   ivory, where muted-on-navy is close to invisible. */
.card-section .form-note { color: var(--muted); margin-top: 14px; }

/* --------------------------------------------------------------------- */
/* Media queries last, per the CSS order rule                             */
/* --------------------------------------------------------------------- */
@media (max-width: 900px) {
  .creds .grid { grid-template-columns: repeat(2, 1fr); }
  .cards, .plaincards { grid-template-columns: 1fr 1fr; }
  .split, .split-narrow, .contact-grid, .card-wrap { grid-template-columns: 1fr; }
  .card-qr { justify-self: center; }
  .card-qr img { width: min(320px, 68vw); height: auto; }
  .foot-grid { grid-template-columns: 1fr 1fr; }
}

@media (max-width: 1260px) {
  .menu-btn {
    display: inline-flex; align-items: center; justify-content: center;
    margin-inline-start: auto; min-width: 44px; min-height: 44px;
    background: transparent; border: 1px solid var(--border-on-navy);
    color: var(--accent); cursor: pointer; font-family: var(--sans);
    letter-spacing: 0.1em; padding: 0 12px;
  }
  nav.primary {
    position: fixed; inset: 66px 0 auto 0; margin: 0;
    background: var(--navy); flex-direction: column; align-items: stretch;
    gap: 0; padding: 8px var(--gap) 22px;
    border-bottom: 1px solid var(--border-on-navy);
    max-height: calc(100vh - 66px); overflow-y: auto;
  }
  nav.primary[hidden] { display: none; }

  /* The minimal header has no menu button, so its nav must never become the
     drawer. Without this it went position:fixed below the bar, covered the
     page heading, and stacked the back link and the language switch into
     three rows. The bug only appeared on the notices and the card, which are
     the pages nobody thinks to test at 390px. */
  .header-minimal nav.primary {
    position: static; inset: auto; flex-direction: row; align-items: center;
    gap: 14px; padding: 0; margin-inline-start: auto;
    background: none; border: 0; max-height: none; overflow: visible;
  }
  .header-minimal nav.primary {
    flex-wrap: nowrap;
  }
  .header-minimal nav.primary a {
    padding: 0; border: 0; font-size: 0.64rem; letter-spacing: 0.1em;
  }
  .header-minimal .back-link { gap: 7px; }
  .header-minimal .back-link::before { width: 14px; }
  nav.primary a {
    padding: 15px 0; border-bottom: 1px solid var(--border-on-navy);
    font-size: 0.9rem;
  }
  /* The language switch is NOT in the drawer. On a trilingual site burying
     it behind a hamburger means a francophone or arabophone visitor has to
     discover a menu before they can read the page at all. It sits in the bar
     at every width.
     Everything below exists to keep brand, switch and menu on ONE row at
     390px. The wordmark subtitle and some tracking give up the space; a
     header that wraps to two rows costs more vertical space above the fold
     than the subtitle was ever worth. */
  /* Back to a single flex row: the centred grid needs room the drawer
     widths do not have. */
  .bar { display: flex; gap: 10px; }
  .wordmark { height: 32px; }
  .lang-switch { order: 2; margin-inline-start: auto; }
  .lang-switch button { padding: 0 8px; min-width: 38px; font-size: 0.62rem; }
  .menu-btn { order: 3; margin-inline-start: 0; padding: 0 10px; font-size: 0.72rem; }
  .cards, .plaincards { grid-template-columns: 1fr; }
  .creds .grid { grid-template-columns: 1fr; }

  /* ==================================================================
     MOBILE DARKNESS, three measured changes.

     The share of dark was never the problem: a phone is 39% dark against
     51% on desktop. What changes is what fits on screen at once. Measured
     as contiguous dark runs against an 844px viewport, the closing call to
     action plus the footer came to 1,300px, 1.5 screens with no light in
     frame at all, so it read as an app background rather than a section of
     a document.

     The navy itself is NOT touched. #0B1326 is what makes the gold read as
     gold; on a lighter blue the same gold goes muddy. The fix is run
     length, not colour depth.
     ================================================================== */

  /* 1. The closing call to action goes ivory, which splits the longest run
        in two. Everything inside it has to flip with the ground, or the
        white primary button becomes an invisible slab on ivory. */
  .cta-band { background: var(--page); color: var(--ink); }
  .cta-band h2 { color: var(--ink); }
  .cta-band .lead { color: var(--muted); }
  .cta-band .btn { background: var(--navy); color: #fff; }
  .cta-band .btn-ghost {
    background: transparent; color: var(--navy); border-color: var(--border);
  }

  /* 2. The footer was 807px, most of it eight page links stacking one per
        line. Two columns roughly halves it. */
  .foot-pages ul { columns: 2; column-gap: 24px; }
  .foot-pages li { break-inside: avoid; }

  /* Tap targets. The footer links are about 20px of text, and dropping the
     type a notch made that worse rather than better. Padding on the anchor
     rather than a larger font: the target grows, the type does not. Margin
     goes to zero so the rows do not also grow by the same amount twice. */
  footer.site li { margin-bottom: 0; }
  footer.site li a { display: inline-block; padding: 8px 0; }
  .foot-legal { gap: 4px 20px; }
  .foot-legal a { display: inline-block; padding: 8px 0; }
  /* The studio credit sits inside a span, so it never inherited the rule
     above and stayed a 15px target. */
  .foot-credit a.studio { display: inline-block; padding: 8px 0; }
  footer.site { padding-top: 24px; }
  .foot-grid { gap: 20px 30px; }

  /* 3. The hero gives back about 60px so a slice of ivory reaches the first
        screenful. On an 844px phone it already did; on a 667px one it did
        not, and that is the screen where the site looked like an app. */
  .hero { padding-top: 30px; padding-bottom: 22px; }
  .motto { margin-bottom: 18px; padding-bottom: 14px; }
  .foot-grid { grid-template-columns: 1fr; }
  .foot-base { grid-template-columns: 1fr; text-align: center; }
  .foot-base > :first-child,
  .foot-base > :last-child,
  .foot-credit { justify-self: center; }
  .foot-legal { justify-content: center; }
  .readings-head { align-items: flex-start; }
  .reading-switch { width: 100%; }
  .reading-switch button { flex: 1; padding: 12px 8px; }
}

/* 320px, the narrowest phone still in use. The bar wrapped to two rows here
   even after the 1180px tightening, so it gets one more turn of the screw
   rather than being allowed to eat 126px above the fold. */
@media (max-width: 360px) {
  .bar { gap: 8px; padding-left: 14px; padding-right: 14px; }
  /* French runs about 15% longer than English and pushed the minimal header
     past 320px. The brand gives up the space, since the back link and the
     language switch are the only two things on this page that do anything. */
  .wordmark { height: 26px; }
  .header-minimal nav.primary a { font-size: 0.58rem; letter-spacing: 0.06em; }
  .header-minimal .back-link::before { width: 10px; }
  .lang-switch button { padding: 0 6px; min-width: 34px; font-size: 0.58rem; }
  .menu-btn { padding: 0 8px; font-size: 0.66rem; }
}

/* A shorter phone needs a little more back. 667px is the iPhone SE, the
   smallest screen still worth designing for, and at that height the header
   plus hero came to 673px: six pixels too tall to let any ivory into the
   first screenful, which is the exact thing these changes exist to fix. */
@media (max-width: 500px) and (max-height: 720px) {
  .hero { padding-top: 22px; padding-bottom: 18px; }
  .hero h1 { font-size: 1.95rem; }
  .hero .lead { margin-top: 18px; }
  .motto { margin-bottom: 14px; padding-bottom: 12px; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: 0.001ms !important; transition-duration: 0.001ms !important; }
}
