/* ============================================================
   BRIGHTSTAR REAL ESTATE — SHARED DESIGN SYSTEM
   Brand Guidelines: Revised 02/19/26

   Single source of truth for tokens, scales and the elements that
   appear on every page (navigation, footer, the stitched leather
   surface). index.html and the legal pages all load this file, so a
   change lands once instead of being made in two places and drifting.

   PALETTE (exact brand hex)
   Primary:   #ECDFD1 #DCD5CF #978A7D #6C6155 #413529
   Secondary: #E6E0AC #ACA374 #7F734F #695927 #594C1E
   Accent:    #591711 (Maroon) #7B2B27 (Light Maroon)
   ============================================================ */

:root {
  /* ---- brand palette ---- */
  --cream:        #ECDFD1;
  --dove:         #DCD5CF;
  --sandstone:    #978A7D;
  --driftwood:    #6C6155;
  --obsidian:     #4F4942;

  --savanna:      #E6E0AC;
  --olive:        #ACA374;
  --herbal:       #7F734F;
  --mosswood:     #695927;
  --ember:        #594C1E;

  --maroon:       #591711;
  --maroon-light: #7B2B27;

  --white:        #FFFFFF;
  --black:        #1A1A1A;

  /* ---- secondary text ----
     The brand greys are tuned for surfaces, not for type: sandstone
     reads 2.57:1 on cream and 2.64:1 on obsidian, driftwood 1.47:1 on
     obsidian — all under the 4.5:1 WCAG AA needs at these sizes. These
     two stay in the same warm family and clear AA on every background
     the site uses. --sandstone and --driftwood keep their jobs on
     borders, rules and other non-text decoration. */
  --text-muted:      #5F554A;  /* 5.56:1 on cream, 5.01:1 on dove */
  --text-muted-dark: #C9BEB1;  /* 4.86:1 on obsidian              */
  /* A field's only visible boundary is a UI component and has to clear 3:1
     (WCAG 1.4.11). --driftwood is 1.47:1 on obsidian and --sandstone 2.64:1,
     so neither of the two "decoration" tokens can carry it. 3.64:1. */
  --field-line:      #B0A498;

  /* ---- type ----
     When Plantin MT Pro is installed, change the first value:
     --font-display: 'Plantin MT Pro', Georgia, serif; */
  --font-display: 'Libre Baskerville', 'Plantin MT Pro', Georgia, serif;
  --font-body:    'Roboto', 'Helvetica Neue', Arial, sans-serif;

  /* Type scale. Replaces 23 ad hoc sizes — several of which sat inside
     a 1px band of each other — with one ladder every element sits on. */
  --fs-micro: 0.6875rem;  /* 11px — eyebrows, legends, meta          */
  --fs-2xs:   0.75rem;    /* 12px — legal, captions, fine print      */
  --fs-xs:    0.8125rem;  /* 13px — nav, buttons, labels             */
  --fs-sm:    0.9375rem;  /* 15px — secondary body, card copy        */
  --fs-md:    1rem;       /* 16px — body                             */
  --fs-lg:    1.125rem;   /* 18px — lead paragraphs, card titles     */
  --fs-xl:    1.25rem;    /* 20px — card + column headings           */
  --fs-2xl:   1.375rem;   /* 22px — minor section headings           */
  --fs-3xl:   clamp(1.75rem, 3.6vw, 2.5rem);   /* section titles     */
  --fs-4xl:   clamp(2.25rem, 6vw, 3.6rem);     /* hero / slide titles */

  --lh-tight: 1.18;
  --lh-snug:  1.45;
  --lh-body:  1.75;

  /* Tracking travels with size: the smaller and more uppercase the
     text, the more it needs. */
  --track-micro: 0.16em;
  --track-label: 0.12em;
  --track-wide:  0.22em;

  /* ---- radius ----
     Previously 18px on one element, 6px on another and 0 everywhere
     else, which made the rounded patch read as an inconsistency rather
     than a deliberate exception. */
  --r-xs:   2px;
  --r-sm:   4px;
  --r-md:   8px;
  --r-lg:   16px;
  --r-full: 999px;

  /* ---- elevation ----
     Three steps, warm-tinted from obsidian rather than neutral black so
     shadows sit in the same family as the surfaces they fall on.
     e-1 resting · e-2 raised/hover · e-3 overlay. */
  --e-1: 0 1px 2px rgba(41,36,31,0.05),
         0 2px 8px -4px rgba(41,36,31,0.14);
  --e-2: 0 2px 4px rgba(41,36,31,0.06),
         0 12px 26px -12px rgba(41,36,31,0.26);
  --e-3: 0 8px 18px rgba(41,36,31,0.10),
         0 30px 64px -22px rgba(41,36,31,0.44);
  --e-dark-1: 0 1px 2px rgba(0,0,0,0.24), 0 2px 10px -4px rgba(0,0,0,0.36);
  --e-dark-2: 0 3px 8px rgba(0,0,0,0.30), 0 16px 34px -14px rgba(0,0,0,0.52);

  /* ---- saddle stitch ----
     The red stitch is the most distinctive mark in the brand, and it acts as a
     system here — dividers, selected states, the leather rings.

     It is drawn from artwork rather than from `border: dashed`, because a
     dashed border is a machine stitch: identical square-ended marks, perfectly
     axis-aligned, perfectly spaced. images/stitch-*.svg are generated with a
     slant across the seam, round thread ends, varying length and lean, a seam
     line that wanders slightly, and a hairline of shade under each stitch so
     the thread reads as sitting proud of the leather.

     One thread color throughout — a workshop works from one spool. */
  --stitch-color:    #98352C;
  --stitch-seam:     url('images/stitch-seam.svg');
  --stitch-ring-art: url('images/stitch-ring.svg');
  --stitch-h:        10px;   /* rendered height of a seam                     */
  --stitch-ring-w:   16px;   /* border width the ring art renders into        */

  /* ---- the hide ----
     Natural, undyed veg-tan. The leather used to be a near-black brown; this
     is the same photographed hide, recoloured channel by channel rather than
     swapped for stock, so the grain the brand already had is the grain it
     keeps. See tools/generate-leather.py.

     On a pale hide the type has to come from the other end of the palette,
     and the ink is not a free choice: measured on the painted pixels rather
     than on a computed background colour, the brand's deep brown carries the
     name tag at 5.27:1 and the dialog body at 4.90:1 here. On the warmer
     russet the same brown misses AA at 4.28, which is what settled the tone.

     The edges are warm browns rather than blacks: a hide has no black in it,
     and a black vignette on a pale ground reads as soot. */
  --leather:            #EAC191;
  --leather-ink:        #413529;   /* 5.27:1 on the tag                       */
  --leather-ink-muted:  #463823;   /* 4.90:1 on dialog body copy              */
  --leather-glow:       rgba(255,252,244,0.55);  /* top edge catch-light      */
  --leather-shade:      rgba(110,76,38,0.40);    /* bottom edge shade         */
  --leather-edge:       rgba(138,101,56,0.46);   /* the cut edge of the hide  */
  --leather-vig:        rgba(138,96,46,0.22);    /* vignette                  */
  --leather-grain:      240px;                   /* see below                 */

  /* ---- spacing ----
     The last scale that was still ad hoc. Section padding on mobile ran
     48 / 70 / 72 / 84 / 90 and stacked grid gaps ran 16 / 18 / 24 / 28 / 40 / 60,
     none of it related, which is what made the phone layout feel cramped in
     some places and loose in others. */
  --sp-1:   4px;
  --sp-2:   8px;
  --sp-3:  12px;
  --sp-4:  16px;
  --sp-5:  24px;
  --sp-6:  32px;
  --sp-7:  40px;
  --sp-8:  56px;
  --sp-9:  72px;
  --sp-10: 96px;
  --sp-11: 120px;

  /* ---- layout ---- */
  --max-width:   1200px;
  --gutter:      40px;
  --section-pad: var(--sp-10) 0;
  /* The height of the bar an anchor actually lands under, which is the
     scrolled one: 74px at every width. At 90 every jump cleared 32px more
     than the nav covers. */
  --nav-h:       74px;

  --t-fast: 0.2s ease;
  --t-med:  0.3s ease;
  /* One long duration, for the carousel's slide and nothing else. It used to
     be a literal 0.7s next to literals of 0.2, 0.25 and 0.3 — four speeds
     against a system that named two. */
  --t-slide: 0.7s ease;
}

/* ============================================
   RESET + BASE
   ============================================ */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

html { scroll-behavior: smooth; }

body {
  font-family: var(--font-body);
  font-weight: 300;
  font-size: var(--fs-md);
  color: var(--obsidian);
  line-height: var(--lh-body);
  background: var(--cream);
  -webkit-font-smoothing: antialiased;
}

img { max-width: 100%; height: auto; display: block; }
a { text-decoration: none; color: inherit; }
button { cursor: pointer; font-family: inherit; }

/* Text zoom scales every measure, and rem-based clamps scale with it: the
   slide title's 2.25rem floor becomes 72px at 200%. Nothing may then set a
   minimum the viewport cannot meet, or the page scrolls sideways and fails
   WCAG 1.4.4. Long words break rather than push. */
h1, h2, h3, h4, h5, h6, p, li, a, dt, dd, figcaption { overflow-wrap: break-word; }

/* Skip link. Every page opens with a navigation list, and on the homepage
   the first landmark after it was 2,000 lines away — a keyboard visitor had
   no way past the menu but to tab through it on every page. */
/* Available to assistive tech, never painted. */
.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: absolute;
  left: var(--gutter);
  top: 0;
  /* Above the nav (1000). At 200 the fixed bar painted straight over the
     chip: measured 1.10:1 on the legal pages, where .nav--solid is opaque, and
     a blurred smear on the homepage. It worked; it just could not be seen. */
  z-index: 1100;
  transform: translateY(-140%);
  padding: 12px 20px;
  border-radius: 0 0 var(--r-sm) var(--r-sm);
  background: var(--cream);
  color: var(--obsidian);
  font-family: var(--font-body);
  font-size: var(--fs-xs);
  font-weight: 500;
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  transition: transform var(--t-med);
}

.skip-link:focus-visible { transform: translateY(0); }

/* Focus stays a plain outline rather than the stitch artwork: an outline
   cannot take an image, and a focus ring's job is to be unmistakable and
   consistent, not characterful.

   It is TWO-TONE, and it has to be. An earlier version used savanna alone with
   a comment claiming it cleared 3:1 on every surface — it does not. Savanna is
   6.61:1 on obsidian but 1.03:1 on cream, 1.08:1 on dove and 1.19:1 on the
   card fill, i.e. effectively invisible across most of the site. No single
   color in this palette clears 3:1 against both the light surfaces and the
   dark ones, so the ring pairs a dark core with a light halo: obsidian carries
   it on cream (6.79:1) and savanna carries it on obsidian (6.61:1). One of the
   two is always visible. */
:focus-visible {
  outline: 2px solid var(--obsidian);
  outline-offset: 2px;
  box-shadow: 0 0 0 5px var(--savanna);
  border-radius: var(--r-xs);
}

.container {
  max-width: var(--max-width);
  margin: 0 auto;
  padding: 0 var(--gutter);
}

/* Anchored sections clear the fixed bar instead of landing under it. */
[id] { scroll-margin-top: calc(var(--nav-h) + 16px); }

/* ============================================
   SADDLE STITCH
   A reusable inset stitch ring. Applied to any positioned element via
   .stitched, and as a horizontal rule via .stitch-rule.
   ============================================ */
/* --- a run of hand stitching, any width, any color ---
   The artwork is white and applied as a mask, so background-color decides the
   thread color. `round` fits a whole number of stitches into the run rather
   than clipping one in half at each end.

   Every seam on the site is drawn here. This utility existed and nothing used
   it: .creed__rule, .footer__divider, the three section-header rules and
   .legal-hero::after each carried their own copy of the same eight
   declarations, and the copies had already drifted. Pseudo-elements cannot
   take a class, so they are named in the selector; the two real elements use
   .stitch-rule in the markup. Each site still supplies its own width and
   margin, which is all that actually differs.

   .nav__links a::after is deliberately not here: it animates its width from
   zero, so it tiles with repeat-x rather than round. */
.stitch-rule,
.stitch-seam,
.services__header::after,
.client-guide__header::after,
.about__intro::after,
.legal-hero::after {
  display: block;
  height: var(--stitch-h);
  border: 0;
  background-color: var(--stitch-color);
  -webkit-mask-image: var(--stitch-seam);
          mask-image: var(--stitch-seam);
  -webkit-mask-repeat: round;
          mask-repeat: round;
  -webkit-mask-position: left center;
          mask-position: left center;
  -webkit-mask-size: auto var(--stitch-h);
          mask-size: auto var(--stitch-h);
}

/* --- a closed ring of hand stitching around a box ---
   The art is 9-sliced, so corners keep their turn at a fixed scale and only the
   straight runs tile. The seam sits at half the border width inside the
   pseudo-element, so the box is pulled in by that much to leave --stitch-inset
   between the stitching and the parent's edge. */
.stitched { position: relative; }

.stitched::after,
.stitch-ring::after {
  content: '';
  position: absolute;
  pointer-events: none;
  inset: calc(var(--stitch-inset, 11px) - var(--stitch-ring-w) / 2);
  border: var(--stitch-ring-w) solid transparent;
  border-image: var(--stitch-ring-art) 16 / var(--stitch-ring-w) / 0 round;
}

/* ============================================
   STITCHED LEATHER SURFACE

   The original art (hero-leather-patch.jpg, 1400x560) carries its
   bevel, stitch and rounded corners baked into the pixels, so it was a
   fixed frame being used as a stretchable texture: painting it with
   background-size stretched the frame to 4:1 in the hero and cropped
   both stitched sides away on mobile, and 9-slicing it left the art's
   own dark corner arc fighting the CSS corner radius.

   So the photograph now supplies texture only and the bevel, stitch and
   corner are drawn in CSS. One corner geometry, no distortion, and it
   holds at any size or aspect ratio.
   ============================================ */
.leather {
  --stitch-inset: 12px;
  /* The two parts of the surface a caller has reason to vary: how far off the
     backdrop the hide sits, and how far the vignette reaches in. Named, so a
     small piece can sit flatter without forking the whole shadow chain — the
     hero's name tag is sewn down rather than floating, and 34px of vignette
     on an 84px tag would close over the middle of it. */
  --leather-elev:     var(--e-dark-2);
  --leather-vignette: 34px;
  position: relative;
  color: var(--leather-ink);
  background-color: var(--leather);
  /* A repeating tile at a fixed size, not cover. cover ties the grain to the
     element: it rendered the photograph at 36% on the 455px name tag and at
     405% on a 520x1700 dialog, so the two surfaces were not the same material
     — one was leather and the other was plaster. On the old near-black hide
     you could not see it. At a fixed size every leather surface on the site
     has the same grain, whatever its shape. */
  background-image: url('images/leather-blonde.jpg');
  background-size: var(--leather-grain) var(--leather-grain);
  background-repeat: repeat;
  border-radius: var(--r-lg);
  box-shadow:
    inset 0 1px 0 var(--leather-glow),      /* top edge catch-light */
    inset 0 -1px 0 var(--leather-shade),    /* bottom edge shade    */
    inset 0 0 0 1px var(--leather-edge),    /* cut edge of the hide */
    inset 0 0 var(--leather-vignette) var(--leather-vig),
    var(--leather-elev);
}

.leather::after {
  content: '';
  position: absolute;
  pointer-events: none;
  inset: calc(var(--stitch-inset) - var(--stitch-ring-w) / 2);
  border: var(--stitch-ring-w) solid transparent;
  border-image: var(--stitch-ring-art) 16 / var(--stitch-ring-w) / 0 round;
}

.leather--sm {
  --stitch-inset: 9px;
  border-radius: var(--r-md);
}

/* ============================================
   NAVIGATION
   One implementation for every page. The legal pages previously ran a
   parallel, thinner nav with no mobile menu at all.
   ============================================ */
.nav {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 1000;
  padding: 20px 0;
  /* 0.55 with saturate(120%) measured 2.67:1 for the cream links against the
     hero loop's brightest sky — the bar reads as glass, but 13px text on it
     has to clear 4.5:1 whatever is playing underneath. Deeper plate, and no
     saturation boost lifting the sky's luminance back up. The blur keeps the
     movement visible through it. */
  background: rgba(63, 58, 52, 0.62);
  -webkit-backdrop-filter: blur(16px);
  backdrop-filter: blur(16px);
  box-shadow: 0 2px 20px rgba(0,0,0,0.12);
  transition: background var(--t-med), padding var(--t-med), box-shadow var(--t-med);
}

/* .scrolled applies from 60px down — i.e. across the whole page, where
   the bar floats over cream and dove. At 0.7 alpha the cream links fell
   to 3.41:1 against those sections; 0.92 keeps the glassy edge and
   holds them at 5.6:1. */
.nav.scrolled,
.nav--solid {
  background: rgba(79, 73, 66, 0.92);
  padding: 12px 0;
  box-shadow: 0 2px 20px rgba(0,0,0,0.18);
}

.nav .container {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.nav__logo-img { height: 50px; width: auto; }

.nav__links {
  display: flex;
  align-items: center;
  gap: 32px;
  list-style: none;
}

/* The Contact item is a <button>, not an <a>: it opens a dialog, so Space has
   to activate it and it must not announce as a link. Both element types share
   one rule so the row cannot drift apart. */
.nav__links { order: 2; }

.nav__links a,
.nav__links button {
  font-family: var(--font-body);
  font-size: var(--fs-xs);
  font-weight: 300;
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--cream);
  background: none;
  border: 0;
  position: relative;
  transition: color var(--t-med);
}

/* Link underline picks up the stitch rhythm rather than a plain rule. */
.nav__links a::after,
.nav__links button::after {
  content: '';
  position: absolute;
  bottom: -7px; left: 0;
  width: 0;
  height: var(--stitch-h);
  background-color: var(--cream);
  -webkit-mask-image: var(--stitch-seam);
          mask-image: var(--stitch-seam);
  -webkit-mask-repeat: repeat-x;
          mask-repeat: repeat-x;
  -webkit-mask-size: auto var(--stitch-h);
          mask-size: auto var(--stitch-h);
  transition: width var(--t-med);
}

.nav__links a:hover::after,
.nav__links button:hover::after { width: 100%; }

.nav__links .nav__cta {
  padding: 9px 22px;
  border: 1px solid var(--sandstone);
  line-height: 1.2;
  border-radius: var(--r-sm);
  transition: background var(--t-med), border-color var(--t-med), color var(--t-med);
}

.nav__links .nav__cta:hover {
  background: var(--cream);
  border-color: var(--cream);
  color: var(--obsidian);
}

.nav__cta::after { display: none !important; }

.nav__agent {
  font-size: var(--fs-2xs) !important;
  letter-spacing: var(--track-label) !important;
  /* Kept secondary by size and tracking rather than by dimming it —
     an 0.8 opacity pushed this below AA against the bar. */
  color: var(--dove) !important;
}

.nav__agent:hover { color: var(--cream) !important; }
.nav__agent::after { display: none !important; }

.nav__toggle {
  /* Source order puts this before #navLinks so that Tab reaches the menu it
     opens; `order` puts it back on the right of the bar. */
  order: 3;
  display: none;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 5px;
  background: none;
  border: none;
  width: 44px;
  height: 44px;
  padding: 10px;
}

.nav__toggle span {
  width: 24px; height: 2px;
  background: var(--cream);
  transition: transform var(--t-fast), opacity var(--t-fast);
}

.nav__toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.nav__toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.nav__toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

/* ============================================
   FOOTER
   ============================================ */
.footer {
  background: var(--obsidian);
  color: var(--cream);
  padding: var(--sp-10) 0 var(--sp-7);
}

.footer__top {
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 56px;
}

.footer__logo-wrap { text-align: center; }
.footer__logo-img { height: 80px; width: auto; }

.footer__logo-sub {
  font-family: var(--font-display);
  font-size: var(--fs-2xs);
  color: var(--text-muted-dark);
  letter-spacing: var(--track-label);
  margin-top: 2px;
}

.footer__divider {
  /* 64px is six stitches, which read as a stray mark rather than a seam. */
  width: 128px;
  margin: 0 auto 50px;
}

.footer__grid {
  display: grid;
  grid-template-columns: 1.6fr 0.9fr 1.3fr;
  gap: 36px;
  padding-bottom: 50px;
  border-bottom: 1px solid rgba(108,97,85,0.35);
}

/* Grid and flex children default to min-width:auto, which refuses to shrink
   below their own min-content width. With text at 200% the footer's email
   address set that minimum and the whole page scrolled sideways — a 1.4.4
   failure that only showed up under zoom. */
.footer__col { min-width: 0; }

.footer__col a,
.footer__col p,
.footer__contact-line { overflow-wrap: break-word; }

.footer__col-title {
  font-family: var(--font-display);
  font-size: var(--fs-sm);
  font-weight: 700;
  color: var(--cream);
  margin-bottom: 16px;
}

.footer__col p,
.footer__col a {
  font-size: var(--fs-sm);
  font-weight: 300;
  color: var(--text-muted-dark);
  line-height: var(--lh-body);
  display: block;
  text-decoration: none;
}

.footer__col a:hover { color: var(--cream); }
.footer__col--links a { display: block; margin-bottom: 4px; }

.footer__social {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 12px;
}

.footer__social a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px; height: 44px;
  /* sandstone clears the 3:1 that WCAG 1.4.11 asks of interactive
     boundaries; driftwood, used before, sat at 1.47:1. */
  border: 1px solid var(--sandstone);
  border-radius: var(--r-sm);
  color: var(--text-muted-dark);
  transition: background var(--t-med), border-color var(--t-med),
              color var(--t-med), transform var(--t-med);
}

.footer__social a svg {
  width: 19px; height: 19px;
  fill: currentColor;
  display: block;
}

.footer__social a:hover {
  background: var(--cream);
  border-color: var(--cream);
  color: var(--obsidian);
  transform: translateY(-2px);
}

/* Equal Housing Opportunity statement, above the copyright line. */
.footer__eho {
  display: flex;
  align-items: flex-start;
  gap: 14px;
  padding-top: 26px;
  color: var(--text-muted-dark);
  font-size: var(--fs-2xs);
  font-weight: 300;
  line-height: 1.7;
  /* 780px of 12px type is about 112 characters a line — roughly twice a
     comfortable measure, in the smallest type the site sets. */
  max-width: 62ch;
}

.footer__eho-mark {
  flex: none;
  width: 34px;
  height: 31px;
  margin-top: 2px;
  fill: var(--text-muted-dark);
}

.footer__bottom {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding-top: 28px;
  font-size: var(--fs-2xs);
  font-weight: 300;
  color: var(--text-muted-dark);
}

.footer__legal { display: flex; gap: 20px; }

.footer__legal a {
  font-size: var(--fs-2xs);
  color: var(--text-muted-dark);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.footer__legal a:hover { color: var(--cream); }

/* ============================================
   RESPONSIVE
   One breakpoint ladder for every page. The legal pages previously ran
   their own (520/768/900) against the main site's (480/600/768/1024).
   ============================================ */
@media (max-width: 1024px) {
  .footer__grid { grid-template-columns: 1fr 1fr; gap: 32px; }
}

@media (max-width: 768px) {
  /* A phone needs proportionally MORE vertical air between blocks than a
     desktop, not less: everything is stacked, so vertical space is the only
     thing separating one idea from the next. */
  :root { --section-pad: var(--sp-9) 0; --gutter: 24px; }

  .nav__links { display: none; }
  .nav__toggle { display: flex; }

  .nav__links.active {
    display: flex;
    flex-direction: column;
    position: absolute;
    top: 100%; left: 0; right: 0;
    /* Fully opaque and a shade darker than obsidian. At 0.98 alpha over an
       obsidian page hero the panel and the hero were the same color, so the
       2% that showed through read as the heading bleeding into the menu. */
    background: #423C36;
    padding: 28px var(--gutter) 32px;
    gap: 18px;
    box-shadow: var(--e-dark-2);
    border-top: 1px solid rgba(236,223,209,0.10);
  }

  .nav__links.active li { width: 100%; text-align: center; }
  /* The 44px touch-target pass covered forms and the footer but skipped the
     primary navigation, which was rendering 38.8px tall and as narrow as
     52.6px. Full-width block links fix both dimensions at once. */
  .nav__links.active a,
  .nav__links.active button {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    min-height: 48px;
    padding: var(--sp-2) var(--sp-4);
  }

  .footer__grid { grid-template-columns: 1fr; gap: var(--sp-7); }
  .footer__eho { flex-direction: column; align-items: center; text-align: center; gap: 10px; }
  .footer__bottom { flex-direction: column; gap: var(--sp-4); text-align: center; }
  .footer__legal { flex-direction: column; gap: 6px; align-items: center; }
  .footer__legal a { min-height: 44px; display: flex; align-items: center; justify-content: center; }
  .footer__col a { padding: 10px 0; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    /* Delays have to go too, not just durations. A staged entrance with a
       delayed fill-mode:both step would otherwise hold its element at the
       from-state for the length of the delay — the hero stitch sat invisible
       for half a second before snapping in. */
    animation-delay: 0s !important;
    transition-delay: 0s !important;
  }
}

/* ============================================
   PRINT
   Chrome repeats every position:fixed element on every printed page, and a
   backdrop-filter paints an opaque plate even when backgrounds are switched
   off. On paper that band landed mid-clause: the Terms lost the opening of
   its warranty disclaimer and the Privacy Policy lost the paragraph stating
   the visitor's rights under the Texas Data Privacy and Security Act. These
   are the two documents people actually keep a copy of.
   ============================================ */
@media print {
  .nav {
    position: static;
    transition: none;
    background: none;
    box-shadow: none;
    -webkit-backdrop-filter: none;
            backdrop-filter: none;
  }

  .skip-link,
  .popup-overlay,
  .video-modal,
  .hero__motion,
  .hero__scroll,
  .slider__arrow,
  .slider__dots,
  .slider__motion,
  .nav__toggle { display: none !important; }

  body { background: #fff; color: #000; }

  main { padding-top: 0; }

  /* A link's destination is worth keeping when the page is on paper. */
  .legal-section a[href^="http"]::after { content: " (" attr(href) ")"; font-size: 0.85em; }

  /* Never split a clause across a page break if it can be helped. */
  .legal-section { break-inside: avoid; }
  h1, h2, h3 { break-after: avoid; }
}
