/* =============================================================================
   AURORA GLASS — Eye Trends design system
   =============================================================================

   This file is the ENTIRE visual language of the site. layout.css positions the
   boxes and contains no colour, type, surface or motion; everything you can see
   is defined here.

   Direction: a luminous aurora ground, frosted glass surfaces floating on it,
   one deep-teal brand accent lit by a gold counterpoint, oversized tight display
   type, and motion that depends on depth rather than decoration.
   ========================================================================== */

/* ---------------------------------------------------------------- 1 · TOKENS */
:root {
  /* brand — anchored to the MEASURED palette in tokens.css, so changing a
     value there restyles the site instead of drifting from it. --c-2 is the
     client's teal, --c-9 their gold-light, --c-3 their deep ink. The two
     additions (--g-teal-lit, --g-gold) are new to this design and have no
     measured equivalent, so they are declared once, here, and nowhere else. */
  --g-teal:        var(--c-2);
  --g-teal-lit:    #16B393;
  --g-teal-deep:   #064A3E;
  --g-gold:        #E0A44C;
  --g-gold-lit:    var(--c-9);

  /* ground */
  --g-ink:         var(--c-3);
  --g-ink-2:       #0D2428;
  --g-paper:       var(--c-5);
  --g-cream:       #FBF7F0;
  --g-mint:        var(--c-4);

  /* text */
  --g-fg:          var(--c-6);
  --g-fg-soft:     var(--c-8);
  --g-fg-faint:    #7C949B;
  --g-on-dark:     var(--c-7);
  --g-on-dark-soft: color-mix(in srgb, var(--c-7) 72%, transparent);

  /* light glass */
  --glass-bg:      color-mix(in srgb, var(--c-1) 58%, transparent);
  --glass-bg-2:    color-mix(in srgb, var(--c-1) 74%, transparent);
  --glass-brd:     color-mix(in srgb, var(--c-1) 80%, transparent);
  --glass-edge:    inset 0 1px 0 color-mix(in srgb, var(--c-1) 90%, transparent), inset 0 -1px 0 color-mix(in srgb, var(--c-3) 5%, transparent);
  --glass-blur:    blur(22px) saturate(175%);
  --glass-shadow:  0 24px 56px -24px color-mix(in srgb, var(--c-3) 30%, transparent), 0 2px 10px color-mix(in srgb, var(--c-3) 5%, transparent);
  --glass-lift:    0 44px 90px -32px color-mix(in srgb, var(--c-3) 40%, transparent), 0 4px 16px color-mix(in srgb, var(--c-3) 8%, transparent);

  /* dark glass */
  --glassd-bg:     color-mix(in srgb, var(--c-3) 58%, transparent);
  --glassd-brd:    color-mix(in srgb, var(--c-1) 14%, transparent);
  --glassd-edge:   inset 0 1px 0 color-mix(in srgb, var(--c-1) 14%, transparent);

  /* accents */
  --grad-brand:    linear-gradient(112deg, var(--g-teal) 0%, var(--g-teal-lit) 52%, var(--g-gold) 120%);
  --grad-text:     linear-gradient(100deg, var(--g-teal-lit), var(--g-teal) 45%, var(--g-gold));
  --grad-gold:     linear-gradient(112deg, var(--g-gold), var(--g-gold-lit));
  --grad-hair:     linear-gradient(90deg, transparent, color-mix(in srgb, var(--c-2) 35%, transparent) 20%, color-mix(in srgb, var(--g-gold) 45%, transparent) 80%, transparent);
  --glow-teal:     0 0 0 1px color-mix(in srgb, var(--g-teal-lit) 20%, transparent), 0 12px 40px -8px color-mix(in srgb, var(--g-teal-lit) 35%, transparent);
  --glow-gold:     0 12px 40px -10px color-mix(in srgb, var(--g-gold) 45%, transparent);

  /* shape + motion */
  --r-sm: 10px;
  --r-md: 16px;
  --r-lg: 24px;
  --r-xl: 32px;
  --r-pill: 999px;
  --ease:      cubic-bezier(.22,1,.36,1);
  --ease-soft: cubic-bezier(.4,0,.2,1);
  --t-fast: .18s;
  --t-mid:  .34s;
  --t-slow: .72s;

  --wrap: 1180px;
  --gutter: clamp(18px, 4vw, 40px);
  --flow: clamp(60px, 7.4vw, 108px);

  /* --- layout.css still resolves spacing through the source's own tokens.
     Redefined here so nothing inherits an old VISUAL value. ---------------- */
  --ds-container-max: var(--wrap);
  --ds-space-2xs: 4px;  --ds-space-xs: 8px;   --ds-space-sm: 14px;
  --ds-space-md: 24px;  --ds-space-lg: 40px;  --ds-space-xl: 64px;
  --ds-space-2xl: 96px;
  --ds-section-py: var(--flow);
  --ds-divider-h: 80px;
  --et-flow: var(--flow);
  --et-gap: clamp(18px, 2.4vw, 30px);
  --et-measure: var(--wrap);
  --et-i: 0;
}

/* ------------------------------------------------------------ 2 · THE GROUND */
*, *::before, *::after { box-sizing: border-box; }

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

body {
  margin: 0;
  min-height: 100%;
  background: var(--g-paper);
  color: var(--g-fg);
  font-family: var(--font-body);
  font-size: 17px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

/* The aurora. Fixed behind everything, drifting slowly. Sections are
   transparent, so this reads through the whole page and gives the glass
   something to refract. */
body::before {
  content: "";
  position: fixed;
  inset: -25vh -20vw;
  z-index: -2;
  background:
    radial-gradient(42% 38% at 18% 12%, color-mix(in srgb, var(--g-teal-lit) 30%, transparent), transparent 62%),
    radial-gradient(38% 40% at 84% 8%,  color-mix(in srgb, var(--g-gold) 26%, transparent), transparent 64%),
    radial-gradient(46% 44% at 72% 74%, color-mix(in srgb, var(--c-2) 24%, transparent),  transparent 66%),
    radial-gradient(40% 36% at 10% 86%, color-mix(in srgb, var(--c-9) 22%, transparent), transparent 64%),
    var(--g-paper);
  filter: blur(10px);
  animation: auroraDrift 34s var(--ease-soft) infinite alternate;
}
@keyframes auroraDrift {
  0%   { transform: translate3d(0,0,0) scale(1); }
  50%  { transform: translate3d(-2.5%, 1.5%, 0) scale(1.06); }
  100% { transform: translate3d(2%, -2%, 0) scale(1.03); }
}

/* Fine grain over the aurora so the gradients never band. */
body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  opacity: .5;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)' opacity='.045'/%3E%3C/svg%3E");
}

img { max-width: 100%; height: auto; display: block; }
a { color: inherit; text-decoration: none; }
::selection { background: color-mix(in srgb, var(--g-teal-lit) 26%, transparent); }

.wrap { width: 100%; max-width: var(--wrap); margin-inline: auto; padding-inline: var(--gutter); }

/* ------------------------------------------------------- 3 · TYPOGRAPHY */
h1, h2, h3, h4,
.et-h1, .et-h2, .et-h3 {
  font-family: var(--font-display);
  font-weight: 700;
  letter-spacing: -.035em;
  line-height: 1.06;
  color: var(--g-fg);
  text-wrap: balance;
  margin: 0 0 .42em;
}
h1, .et-h1, .ethc-hero__h { font-size: clamp(36px, 5.1vw, 68px); }
h2, .et-h2              { font-size: clamp(27px, 3.5vw, 45px); }
h3, .et-h3              { font-size: clamp(19px, 1.9vw, 24px); letter-spacing: -.02em; line-height: 1.16; }
h4                      { font-size: clamp(17px, 1.6vw, 20px); letter-spacing: -.015em; }

/* the one accent move on headings: a gradient-filled span */
.et-ac, .et-h2 em, h1 em, h2 em, .grad {
  font-style: normal;
  background: var(--grad-text);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
}

p { margin: 0 0 1.05em; }
p:last-child { margin-bottom: 0; }

.et-lede, .dc-lead, .lede, .ha-hero__lede, .tib-hero__lede, .od-hero__lede {
  font-size: clamp(17px, 1.35vw, 19.5px);
  line-height: 1.6;
  color: var(--g-fg-soft);
  max-width: 66ch;
}

.site-content p, .site-content li { color: var(--g-fg-soft); }
.site-content strong, .site-content b { color: var(--g-fg); font-weight: 650; }

/* prose links: gradient underline that fills on hover */
.site-content p > a, .site-content li > a, .dc-prose a, .foot-blurb a {
  color: var(--g-teal);
  background-image: linear-gradient(var(--g-gold), var(--g-gold));
  background-size: 0% 2px;
  background-repeat: no-repeat;
  background-position: 0 100%;
  box-shadow: inset 0 -2px 0 color-mix(in srgb, var(--c-2) 22%, transparent);
  transition: background-size var(--t-mid) var(--ease), color var(--t-mid) var(--ease);
}
.site-content p > a:hover, .site-content li > a:hover, .dc-prose a:hover, .foot-blurb a:hover {
  background-size: 100% 2px;
  color: var(--g-teal-deep);
}

/* ---------------------------------------------------------- 4 · EYEBROWS */
.et-eyebrow, .eyebrow, .ha-eyebrow, .tib-eyebrow, .od-eyebrow, .dc-eyebrow {
  display: inline-flex;
  align-items: center;
  font-family: 'Space Mono', ui-monospace, monospace;
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--g-teal);
  margin: 0 0 18px;
}
/* The 40x2px gold bar that used to sit here rendered as an em-dash before every
   section title ("— CLEAR LAKE EYE DOCTOR SINCE 1984"). Removed on request.
   The eyebrow now carries its weight through colour, tracking and case alone. */
@keyframes ruleIn { from { transform: scaleX(0); } to { transform: scaleX(1); } }

/* ------------------------------------------------- 5 · SECTION RHYTHM */
.rw-sec {
  position: relative;
  padding-block: var(--flow);
  background: transparent;          /* the aurora shows through */
}
.rw-sec > .container { max-width: var(--wrap); margin-inline: auto; padding-inline: var(--gutter); }

/* Tinted veils rather than solid bands — the ground stays visible. */
.et-band--paper {
  background: linear-gradient(180deg, color-mix(in srgb, var(--c-1) 66%, transparent), color-mix(in srgb, var(--c-1) 34%, transparent));
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
.et-band--warm {
  background: linear-gradient(180deg, color-mix(in srgb, var(--g-cream) 78%, transparent), color-mix(in srgb, var(--g-cream) 42%, transparent));
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}

/* Dark bands are deep glass with their own inner light. */
.surface-dark {
  position: relative;
  isolation: isolate;
  color: var(--g-on-dark);
  background:
    radial-gradient(60% 70% at 78% 10%, color-mix(in srgb, var(--g-teal-lit) 30%, transparent), transparent 64%),
    radial-gradient(52% 62% at 12% 92%, color-mix(in srgb, var(--g-gold) 22%, transparent), transparent 66%),
    linear-gradient(165deg, var(--g-ink-2), var(--g-ink));
  border-block: 1px solid color-mix(in srgb, var(--c-1) 8%, transparent);
}
.surface-dark::after {
  content: "";
  position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background: url(/eyetrends-clearlake/assets/generated/grid-glow.webp) center/cover no-repeat;
  opacity: .22;
  mix-blend-mode: screen;
}
.surface-dark :is(h1,h2,h3,h4,.et-h1,.et-h2,.et-h3) { color: var(--c-1); }
.surface-dark :is(p, li, .et-lede, .dc-lead, .lede) { color: var(--g-on-dark-soft); }
.surface-dark .et-eyebrow, .surface-dark .eyebrow { color: var(--g-gold-lit); }
.surface-dark .et-ac { background: linear-gradient(100deg, var(--g-gold-lit), var(--g-teal-lit)); -webkit-background-clip: text; background-clip: text; }

/* Seam: a soft light bleed between bands instead of a hard edge. */
.et-band--seam::before {
  content: "";
  position: absolute; left: 0; right: 0; top: -1px; height: 120px;
  pointer-events: none;
  background: linear-gradient(180deg, color-mix(in srgb, var(--c-1) 55%, transparent), transparent);
}

/* ------------------------------------------------------ 6 · GLASS PRIMITIVE */
/* Only the generic utility lives here. Every real component selector is
   assigned in components.css, generated from audit/redesign-brief.json — the
   output of a pass that read the actual markup. Hand-guessed lists used to sit
   here and got .dc-pill wrong (it is a hairline row, not a card). */
.glass {
  position: relative;
  background: var(--glass-bg);
  -webkit-backdrop-filter: var(--glass-blur);
  backdrop-filter: var(--glass-blur);
  border: 1px solid var(--glass-brd);
  border-radius: var(--r-lg);
  box-shadow: var(--glass-shadow), var(--glass-edge);
  transition: transform var(--t-mid) var(--ease),
              box-shadow var(--t-mid) var(--ease),
              border-color var(--t-mid) var(--ease);
}
.glass:hover { transform: translateY(-6px); box-shadow: var(--glass-lift), var(--glass-edge); }

/* ------------------------------------------------------------ 8 · BUTTONS */
.btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-26);
  font-family: Inter, system-ui, sans-serif;
  font-size: 15.5px;
  font-weight: 600;
  letter-spacing: -.01em;
  padding: var(--sp-36) var(--sp-54);
  border: 1px solid transparent;
  border-radius: var(--r-pill);
  cursor: pointer;
  overflow: hidden;
  isolation: isolate;
  transition: transform var(--t-fast) var(--ease),
              box-shadow var(--t-mid) var(--ease),
              color var(--t-mid) var(--ease),
              border-color var(--t-mid) var(--ease);
}
.btn-lg { padding: var(--sp-41) var(--sp-59); font-size: 16.5px; }

.btn-primary { color: var(--c-1); background: var(--grad-brand); box-shadow: var(--glow-teal); }
/* the sweep: a light band that crosses the button on hover */
.btn-primary::after {
  content: "";
  position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(100deg, transparent 20%, color-mix(in srgb, var(--c-1) 38%, transparent) 50%, transparent 80%);
  transform: translateX(-120%);
  transition: transform var(--t-slow) var(--ease);
}
.btn-primary:hover { transform: translateY(-3px); box-shadow: 0 0 0 1px color-mix(in srgb, var(--g-teal-lit) 30%, transparent), 0 22px 50px -12px color-mix(in srgb, var(--g-teal-lit) 55%, transparent); }
.btn-primary:hover::after { transform: translateX(120%); }

.btn-ghost {
  color: var(--g-fg);
  background: var(--glass-bg);
  -webkit-backdrop-filter: var(--glass-blur);
  backdrop-filter: var(--glass-blur);
  border-color: var(--glass-brd);
  box-shadow: var(--glass-edge);
}
.btn-ghost:hover { transform: translateY(-3px); border-color: color-mix(in srgb, var(--g-teal-lit) 50%, transparent); color: var(--g-teal); box-shadow: var(--glass-shadow); }

.btn-onDark { color: var(--g-ink); background: var(--grad-gold); box-shadow: var(--glow-gold); }
.btn-onDark:hover { transform: translateY(-3px); box-shadow: 0 22px 50px -12px color-mix(in srgb, var(--g-gold) 60%, transparent); }
.btn-onWarm { color: var(--c-1); background: var(--grad-brand); box-shadow: var(--glow-teal); }
.btn-onWarm:hover { transform: translateY(-3px); }

.surface-dark .btn-ghost {
  color: var(--c-1); background: color-mix(in srgb, var(--c-1) 8%, transparent);
  border-color: color-mix(in srgb, var(--c-1) 24%, transparent);
}
.surface-dark .btn-ghost:hover { background: color-mix(in srgb, var(--c-1) 16%, transparent); border-color: color-mix(in srgb, var(--c-1) 40%, transparent); color: var(--c-1); }

/* arrow nudge */
.btn .arw, .et-golink svg, .dc-rel__go svg, .ha-cond__go svg {
  transition: transform var(--t-mid) var(--ease);
}
.btn:hover .arw, .et-golink:hover svg, .dc-rel__go:hover svg, .ha-cond__go:hover svg { transform: translateX(4px); }

/* inline "go" links */
/* CTA links.
   .tib-wayfinding a and .od-close__links a used to be in this list and were
   removed: both are SECTION-level classes, so the descendant selector matched
   every anchor inside them, not the go-links it was written for. A census of
   the build found 28 .et-cat cards, 2 .tib-creed__pillar cards, 1 .btn and a
   single .et-golink inside .tib-wayfinding - so the rule was styling four
   cards and a button for the sake of one link that already carries .et-golink
   and is matched by name here. Making a card inline-flex shrink-wraps it to
   its absolutely positioned content, i.e. to nothing: measured at 390px, those
   tiles rendered 1px wide inside a 337px column and lost their photographs.
   .od-close__links held only .et-golink and .btn, so it was redundant too. */
.et-golink, .dc-rel__go, .ha-cond__go {
  display: inline-flex; align-items: center; gap: var(--sp-19);
  font-weight: 620; font-size: var(--fs-19);
  color: var(--g-teal);
  transition: color var(--t-mid) var(--ease), gap var(--t-mid) var(--ease);
}
.et-golink:hover, .dc-rel__go:hover, .ha-cond__go:hover { color: var(--g-teal-deep); gap: var(--sp-30); }
.surface-dark :is(.et-golink, .dc-rel__go, .ha-cond__go) { color: var(--g-gold-lit); }

/* --------------------------------------------- 9 · STAT TILES & LABELS ---- */
/* Pills, stat numbers and rows are assigned in components.css. What stays here
   is the shared tile surface and the label typography they all share. */
.ethc-hero__stat, .et-stat, .ia-stat, .bw-stat, .dc-proof__i {
  padding: var(--sp-43) var(--sp-45);
  background: var(--glass-bg);
  -webkit-backdrop-filter: var(--glass-blur);
  backdrop-filter: var(--glass-blur);
  border: 1px solid var(--glass-brd);
  border-radius: var(--r-md);
  box-shadow: var(--glass-edge);
}
.ethc-hero__l, .et-stat__l, .dc-proof__l, .od-record__l, .bw-stat__l, .ia-stat__suf {
  display: block;
  margin-top: var(--sp-10);
  font-size: var(--fs-6);
  font-weight: 600;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--g-fg-faint);
}
.surface-dark :is(.ethc-hero__stat, .et-stat, .ia-stat, .dc-proof__i) {
  background: color-mix(in srgb, var(--c-1) 7%, transparent);
  border-color: color-mix(in srgb, var(--c-1) 16%, transparent);
}
.surface-dark :is(.ethc-hero__l, .et-stat__l, .dc-proof__l, .bw-stat__l) { color: color-mix(in srgb, var(--c-7) 62%, transparent); }

/* ---------------------------------------------------- 11 · ICON CHIPS / FAQ */
.dc-visit__ic, .dc-rel__ic, .dc-pill__ic, .et-svc__ico, .ia-ic, .ha-cond__ic, .dc-faq__ic {
  flex: none;
  display: grid;
  place-items: center;
  width: 46px;
  height: 46px;
  border-radius: 14px;
  color: var(--g-teal);
  background: linear-gradient(150deg, color-mix(in srgb, var(--g-teal-lit) 16%, transparent), color-mix(in srgb, var(--g-gold) 14%, transparent));
  border: 1px solid color-mix(in srgb, var(--c-1) 70%, transparent);
  box-shadow: inset 0 1px 0 color-mix(in srgb, var(--c-1) 90%, transparent);
}
.surface-dark :is(.dc-visit__ic, .dc-rel__ic, .et-svc__ico, .dc-faq__ic) {
  color: var(--g-gold-lit);
  background: color-mix(in srgb, var(--c-1) 9%, transparent);
  border-color: color-mix(in srgb, var(--c-1) 16%, transparent);
  box-shadow: inset 0 1px 0 color-mix(in srgb, var(--c-1) 14%, transparent);
}
.dc-faq__item { padding: var(--sp-10) var(--sp-45); margin-bottom: var(--sp-30); }
.dc-faq__q, .dc-faq__item > summary {
  cursor: pointer;
  font-family: var(--font-display);
  font-weight: 650;
  font-size: 17.5px;
  letter-spacing: -.015em;
  color: var(--g-fg);
  padding: 14px 0;
  list-style: none;
}
.dc-faq__item > summary::-webkit-details-marker { display: none; }
.dc-faq__a { color: var(--g-fg-soft); padding-bottom: var(--sp-33); }

/* ------------------------------------------------------------- 12 · QUOTES */
blockquote, .et-review__q, .bw-quote {
  position: relative;
  font-family: var(--font-display);
  font-size: clamp(19px, 2vw, 24px);
  font-weight: 500;
  line-height: 1.4;
  letter-spacing: -.02em;
  color: var(--g-fg);
}
.et-review__src, .bw-quote__src { font-size: 13.5px; color: var(--g-fg-faint); font-weight: 600; }

/* ---------------------------------------------------- 13 · SCROLL REVEAL */
/* Blur-in + rise. Distinct from the source (which never animated at all). */
/* NO scale() here. A section that is itself a reveal target was being drawn at
   98.5% width, so its content edge sat 9px inward until it revealed and then
   snapped — measured on /services/: content-left 170 before, 161 after, on five
   sections. Translate and fade only; scaling a full-width block moves its edges. */
.reveal {
  opacity: 0;
  transform: translateY(26px);
  filter: blur(10px);
  transition:
    opacity var(--t-slow) var(--ease),
    transform var(--t-slow) var(--ease),
    filter var(--t-slow) var(--ease);
  will-change: opacity, transform, filter;
}
.reveal.in-view { opacity: 1; transform: none; filter: blur(0); }
.et-reveal.reveal { transform: translateY(26px); }
.et-reveal.reveal.in-view { transform: none; }

/* ----------------------------------------------------- 14 · REDUCED MOTION */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
  body::before { animation: none; }
  .reveal, .et-reveal.reveal { opacity: 1 !important; transform: none !important; filter: none !important; }
  .rf-progress { display: none; }
}

/* ---------------------------------------------------- 15 · HERO COMPOSITION */
/* The hero copy column is long by content (eyebrow + 3-line H1 + lede + five
   chips + two CTAs + three stats). Centring the media against it pushed the
   image to y=489 on a 650px viewport — below the fold on load. Top-align it,
   and let it stick while the copy scrolls past. */
.ethc-hero__grid,
.ha-hero__inner,
.tib-hero__grid,
.od-hero__grid { align-items: start; }

.ethc-hero { padding-block: clamp(28px, 4vw, 56px) var(--flow); }

@media (min-width: 1041px) {
  /* .ethc-hero__media is full-bleed now and must not stick; .tib-hero__media
     is still a column image, so it keeps the behaviour. */
  .tib-hero__media { position: sticky; top: 108px; }
}

/* The floating proof badge reads as a glass chip lifted off the image. */
.ethc-hero__badge {
  background: color-mix(in srgb, var(--c-1) 74%, transparent);
  -webkit-backdrop-filter: blur(18px) saturate(180%);
  backdrop-filter: blur(18px) saturate(180%);
  border: 1px solid var(--glass-brd);
  border-radius: var(--r-md);
  box-shadow: var(--glass-shadow), var(--glass-edge);
}
/* .rw-sec scoping: layout.css's `.ethc-hero__badge span { display: block }`
   (0,1,1) outranked the bare `.ethc-hero__ring` (0,1,0), so the ring rendered
   as a block, place-items never applied, and the check sat 7.5px left of and
   6.9px above the ring's centre at every desktop width. */
.rw-sec .ethc-hero__ring {
  display: grid; place-items: center;
  width: 34px; height: 34px; border-radius: 50%;
  color: var(--c-1);
  background: var(--grad-brand);
  box-shadow: var(--glow-teal);
}

/* stats sit in a row of glass tiles */
.ethc-hero__proof, .et-stats { display: flex; flex-wrap: wrap; gap: var(--sp-33); margin-top: var(--sp-55); }
.ethc-menu { display: flex; flex-wrap: wrap; gap: var(--sp-26); margin: 24px 0 4px; }
.et-cta-cluster { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-33); margin-top: var(--sp-54); }

/* The proof badge: layout.css leaves it position:relative at top:-22px, so it
   escaped the frame's overflow:hidden and got its top row clipped. Anchor it
   inside the frame as a glass overlay, which is what it reads as anyway. */
.ethc-hero__media .ethc-hero__badge {
  position: absolute;
  inset: auto 18px 18px 18px;
  z-index: 2;
  display: flex;
  align-items: center;
  gap: 13px;
  padding: 13px var(--sp-41);
}
.ethc-hero__badge b { display: block; font-weight: 700; color: var(--g-fg); font-size: var(--fs-16); }
.ethc-hero__badge span span,
.ethc-hero__badge > span > span { display: block; font-size: var(--fs-8); color: var(--g-fg-soft); }

/* =============================================================================
   16 · ONE ALIGNMENT RULE
   Every block in a section starts on the container's content edge. layout.css
   auto-centres a handful of blocks (.et-sec-head x6, .et-lede, .bw-team,
   .ethc-stance__q, .ha-hero__inner), which left their headings flush-left and
   the block beneath them inset — measured at 70px on /our-doctor/. Left-align
   them and keep the measure as a max-width instead of a centring device.
   ========================================================================== */
.rw-sec :is(.et-sec-head, .et-lede, .bw-team, .ethc-stance__q, .od-bio, .ia-callout) {
  margin-inline-start: 0;
  margin-inline-end: 0;
}
.rw-sec .col--measure { margin-inline: 0; max-width: var(--et-measure); }

/* Cards carry their own padding, so an image inside one is meant to be inset.
   Blocks that are NOT cards share the text column exactly. */
.rw-sec > .container > .row > .col > :is(p, h1, h2, h3, ul, ol) { margin-inline-start: 0; }

/* Consistent vertical rhythm between a section head and the body that follows */
.row--head { margin-bottom: clamp(28px, 3.4vw, 52px); }
.et-sec-head + * { margin-top: 0; }
.et-lede { margin-top: 14px; }

/* =============================================================================
   17 · FULL-WIDTH HERO
   The hero image spans the full viewport. The media column is lifted out of the
   grid and becomes the section's background; the copy sits over a scrim in the
   normal content column, so it still aligns with every other section.
   ========================================================================== */
.ethc-hero {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  display: flex;
  align-items: center;
  min-height: clamp(560px, 82vh, 860px);
  padding-block: clamp(56px, 8vw, 104px);
  border-radius: 0;
}
/* the grid collapses to one column — the media no longer occupies a track */
.ethc-hero .ethc-hero__grid { grid-template-columns: 1fr; display: block; }
/* The container must stay STATIC. Positioning it made it the media's containing
   block (so the image stopped at the 1180px column instead of going full-bleed)
   AND created a stacking context that painted the image over the scrim. The
   copy is raised on its own instead. */
.ethc-hero .container { position: static; width: 100%; }
.ethc-hero .ethc-hero__copy { position: relative; z-index: 2; }

.ethc-hero .ethc-hero__media {
  position: absolute;
  inset: 0;
  z-index: 0;
  width: 100%;
  height: 100%;
  aspect-ratio: auto;      /* layout.css pins 5/6 and 16/11 */
  max-width: none;
  max-height: none;        /* layout.css caps at min(72vh) and 440px */
  min-height: 0;
  margin: 0;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  overflow: hidden;
  opacity: 1;
  transform: none;
  filter: none;
}
.ethc-hero .ethc-hero__media::after { content: none; }
.ethc-hero .ethc-hero__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 62% 45%;
  transform: none;
}
/* The scrim lives INSIDE the media, not on the section. As a section ::before it
   never painted over the image — forced to solid red it was still invisible —
   so it is attached to the media element instead, where it is unambiguously
   above the <img> it has to darken. */
.ethc-hero .ethc-hero__media::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  /* Strong only where the copy sits, clearing completely by two-thirds across so
     the room is actually visible — the point of a full-width image hero. */
  background:
    /* Stops chosen by measurement, not eye: compositing the scrim over a
       worst-case WHITE photo, the copy zone (x 7%..38%) must clear 4.5:1 for
       body text. The previous ramp fell to 3.85:1 at x=38%; this holds 7.67:1
       there and still clears completely by 92% so the room reads. */
    linear-gradient(90deg,
      color-mix(in srgb, var(--c-3) 90%, transparent) 0%,
      color-mix(in srgb, var(--c-3) 82%, transparent) 30%,
      color-mix(in srgb, var(--c-3) 64%, transparent) 50%,
      color-mix(in srgb, var(--c-3) 22%, transparent) 72%,
      transparent 92%),
    linear-gradient(0deg, color-mix(in srgb, var(--c-3) 34%, transparent) 0%, transparent 26%);
}

/* copy on the scrim */
.ethc-hero .ethc-hero__copy { max-width: 44rem; opacity: 1; transform: none; filter: none; }
.ethc-hero .ethc-hero__h { color: var(--c-1); }
.ethc-hero .ethc-hero__sub { color: color-mix(in srgb, var(--c-7) 86%, transparent); font-size: clamp(17px, 1.4vw, 20px); max-width: 40rem; }
.ethc-hero .et-eyebrow { color: var(--g-gold-lit); }
.ethc-hero .ethc-menu__chip {
  color: var(--c-1);
  background: color-mix(in srgb, var(--c-1) 10%, transparent);
  border-color: color-mix(in srgb, var(--c-1) 22%, transparent);
  box-shadow: inset 0 1px 0 color-mix(in srgb, var(--c-1) 16%, transparent);
}
.ethc-hero .ethc-menu__chip svg { color: var(--g-gold-lit); }
.ethc-hero .ethc-herocall { color: var(--c-1); }
.ethc-hero .ethc-herocall:hover { color: var(--g-gold-lit); }

/* stats become a glass strip sitting on the image */
.ethc-hero .ethc-hero__proof { margin-top: clamp(28px, 3.4vw, 44px); gap: 12px; }
/* Dark glass, not light. At 768px the stats wrap and the third tile lands where
   the scrim has cleared, so a 9%-white tile left its label at 1.51:1 over the
   bright part of the photo. A dark tile reads on any backdrop. */
.ethc-hero .ethc-hero__stat {
  background: color-mix(in srgb, var(--c-3) 62%, transparent);
  border-color: color-mix(in srgb, var(--c-1) 20%, transparent);
  -webkit-backdrop-filter: blur(18px) saturate(160%);
  backdrop-filter: blur(18px) saturate(160%);
}
.ethc-hero .ethc-hero__k {
  background: linear-gradient(100deg, var(--c-1), var(--g-gold-lit));
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent; color: transparent;
}
.ethc-hero .ethc-hero__l { color: color-mix(in srgb, var(--c-7) 84%, transparent); }

/* the proof badge anchors to the bottom-right of the section, not the frame */
.ethc-hero .ethc-hero__badge {
  position: absolute;
  inset: auto clamp(18px, 4vw, 40px) clamp(18px, 3vw, 34px) auto;
  left: auto;
  z-index: 3;
}
@media (max-width: 900px) {
  .ethc-hero { min-height: clamp(520px, 78vh, 720px); }
  .ethc-hero::before {
    background:
      linear-gradient(180deg, color-mix(in srgb, var(--c-3) 80%, transparent) 0%, color-mix(in srgb, var(--c-3) 68%, transparent) 48%, color-mix(in srgb, var(--c-3) 82%, transparent) 100%);
  }
  .ethc-hero .ethc-hero__badge { display: none; }
}

/* =============================================================================
   18 · REVISION-3 CORRECTIONS
   Each rule below answers a measured defect, noted with the measurement.
   ========================================================================== */

/* --- a · service cards were unequal heights ------------------------------
   The .row--svc grid stretched each .col to 381px but the card inside kept its
   content height (353px on two of six). Cards fill their cell; the flex column
   plus margin-top:auto on the footer then pins every "go" link to the same
   baseline. This is the pattern the component map called for. */
.row--svc > .col,
.row--frames > .col,
.row--cards > .col { display: flex; }
.row--svc > .col > *,
.row--frames > .col > *,
.row--cards > .col > * { width: 100%; }
.et-svc, .et-cat, .dc-rel, .ha-cond, .ia-link, .bw-team__member, .dc-relhub {
  height: 100%;
}
.et-svc { display: flex; flex-direction: column; }
.et-svc__foot, .dc-rel__go, .ha-cond__go { margin-top: auto; }

/* --- b · split rows put image and text on different baselines -------------
   .row--split-media is align-items:center, so on the doctor section the image
   column started at y=3583 while the text column started at y=3425 — 158px out
   of step, which is what read as "all over the place". Top-align both. */
/* Specificity matters here: layout.css carries `.rw-sec .row--split-media
   { align-items: center }` at (0,2,0), which beat a bare class selector. Match
   its specificity so the later rule wins. */
.rw-sec .row--split,
.rw-sec .row--split-media,
.rw-sec .row--media-split { align-items: start; }

/* --- c · designer house logos were unreadable -----------------------------
   .ethc-house was a WHITE PILL in the original; the component map said to keep
   it bare, so the dark brand wordmarks ended up on the aurora with nothing
   behind them. The pill comes back as light glass, and every logo is normalised
   to one optical height (they ranged 31px to 73px because each brand's artwork
   has a different aspect ratio). */
/* The pill row still ships on /products/designer-frames/, where this block
   carries the brand NAMES as text instead of wordmark images and so is not the
   row the client asked to unpack. The marquee rules below override every one of
   these inside .ethc-marquee, at higher specificity.

   .ethc-houses has to keep its own rule here. layout.css lays this block out as
   display:grid with repeat(3,1fr) at narrow widths, and a text pill cannot
   shrink below its content: dropping this rule put the "Lindberg" pill 34px
   past the right edge at 390px and gave the page a horizontal scrollbar. A
   wrapping flex row lets the pills reflow instead. */
.ethc-houses {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
}
.ethc-house {
  min-width: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 56px;
  padding: 10px 20px;
  border-radius: var(--r-pill);
  background: color-mix(in srgb, var(--c-1) 82%, transparent);
  -webkit-backdrop-filter: blur(14px) saturate(160%);
  backdrop-filter: blur(14px) saturate(160%);
  border: 1px solid var(--glass-brd);
  box-shadow: var(--glass-edge), var(--glass-shadow);
  transition: transform var(--t-fast) var(--ease), border-color var(--t-mid) var(--ease);
}
.ethc-house:hover {
  transform: translateY(-2px);
  border-color: color-mix(in srgb, var(--g-teal-lit) 45%, transparent);
}
.surface-dark .ethc-house {
  background: color-mix(in srgb, var(--c-1) 92%, transparent);
}

/* =========================================================================
   22 · THE HERO PROOF ROW ON A PHONE
   =========================================================================
   .ethc-hero__proof is a wrapping flex row. That is right on a wide screen and
   wrong on a narrow one: each stat wraps onto its own line at its own content
   width, so the three boxes measured 190, 206 and 164 wide inside a 339px
   column - a ragged left edge that reads as broken rather than designed - and
   together they ate 324px of vertical space in a hero that was already 1153px
   tall at 390px.

   Three equal columns instead. The labels are short enough to take it, and the
   numbers stay the loudest thing in the row.

   Compound selector, not descendant: .ethc-hero sits ON the .rw-sec element,
   so `.rw-sec .ethc-hero` matches nothing at all. Same trap as .et-doctor in
   revision 8 - written once, repeated here, caught by measuring the computed
   display rather than by reading the file back. */
@media (max-width: 640px) {
  .rw-sec.ethc-hero .ethc-hero__proof {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 8px;
  }
  .rw-sec.ethc-hero .ethc-hero__stat {
    min-width: 0;
    padding: 10px 9px;
    gap: 1px;
  }
  .rw-sec.ethc-hero .ethc-hero__k {
    font-size: clamp(19px, 5.6vw, 25px);
    line-height: 1.1;
  }
  .rw-sec.ethc-hero .ethc-hero__l {
    font-size: 9.5px;
    line-height: 1.3;
    letter-spacing: .05em;
  }
}

/* =========================================================================
   21 · MOBILE TOUCH SPACING
   =========================================================================
   Adjacent pills and go-links measured ~7.5px apart on a phone, which is under
   the 8px a finger needs to tell two targets apart. The pills themselves are
   large enough; it is only the gap between them that was tight. */
@media (max-width: 860px) {
  /* Containers named from measurement, not from guessing which ones hold
     pills: these are the three whose adjacent links measured 7-8px apart on a
     phone (.bw-team__contact, .od-close__links, .ha-ins), plus the chip rows. */
  .rw-sec .et-chips,
  .rw-sec .ethc-why__tags,
  .rw-sec .ha-ins__tags,
  .rw-sec .ha-ins,
  .rw-sec .od-close__links,
  .rw-sec .bw-team__contact { gap: 12px; }
  .rw-sec .et-cta-cluster { gap: 14px; }
}

/* =========================================================================
   20 · SIDE-BY-SIDE ROWS: THE SLACK COLUMN
   =========================================================================
   REVISION 8. Client: "fix spaces and padding errors".

   Section rhythm was already even - 107px top and bottom on eleven of twelve
   homepage bands, every seam 0px - and the container insets were symmetric, so
   the spacing fault was not at section level at all. It was INSIDE the
   side-by-side rows: a tall text column next to a short media column, top
   aligned, which dumps every pixel of the difference as dead space under the
   image. Measured at 1440px across fourteen pages, 22 rows were like this:

     /patient-forms/               955 vs 360   595px of slack
     /services/childrens-eye-care/ 1033 vs 520  513px
     /insurance/                   844 vs 376   467px
     /products/                    1107 vs 658  449px
     ... down to 199px

   Two rules fix it, and they are deliberately different because the pictures
   are different.

   a - EVERY media column centres its contents. Whatever slack remains is split
       above and below instead of piling up underneath, which reads as composed
       rather than as a gap. This is the only rule portraits get.
   b - SCENE photography additionally fills the column, so tops and bottoms line
       up and the slack goes to zero. This is the better result and it is what
       the earlier "alignment all over the place" note was asking for too - but
       it crops, so it is applied by name to room and product shots only.

   .et-doctor__media is excluded from (b) on purpose: it holds a photograph of
   Dr. Hyder at 511x560, and filling a 1093px column with it would crop through
   his face. A portrait gets centred, never stretched. */
.rw-sec :is(.row--split, .row--split-media, .tib-hero__grid) > .col:not(:only-child):is(
    :has(> [class*="media"]), :has(> [class*="portrait"]), :has(> img), :has(> picture)) {
  /* align-self:stretch is load-bearing. The row is top-aligned, so without it
     the column is only as tall as its contents and the height:100% below
     resolves against an auto height - which collapsed the media to nothing and
     emptied the right-hand column on /patient-forms/ and /insurance/. The
     column has to own the full row height before anything can fill it. */
  align-self: stretch;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

/* (b) scene photography fills its column. Capped so a very long text column
   cannot stretch a room into a letterbox; past the cap the rule above centres
   what is left. */
/* NO media is stretched to fill its column, and that is a decision, not an
   omission. Filling looked excellent on the pages I first tried it on, and it
   is what removes the slack completely - but the same class holds a different
   photograph on every page. .tib-hero__media is a 1200x1586 PORTRAIT of the
   frame wall on /products/designer-frames/ and a 1600x772 WIDE shot of the
   storefront on /eye-health/ and /reviews/. Filling by class therefore cannot
   be safe: it squeezed that storefront into a 533x797 box, a 3.1x tightening
   that cut through the fascia so the practice's own sign read "EYE o TREN".

   Distinguishing them needs each image's intrinsic size, which this stylesheet
   does not have. So the rule above centres every media column and nothing is
   resized: the slack is split above and below instead of piling under the
   picture, and not one photograph is re-cropped. */

/* Stacked layouts have a single column, so there is no slack to distribute and
   the centring above is a no-op there. Nothing to undo. */

/* --- the homepage doctor section -----------------------------------------
   REVISION 7. The client asked for the two stat tiles out, the "More about
   Dr. Hyder" link moved under the portrait, and the space that left tidied up.

   The tiles carried `margin-top: --ds-space-lg` plus `padding-top:
   --ds-space-lg` of their own, so removing them takes that spacing with them.
   What is left is the moved link, which needs a gap from the role line above it
   but nothing like the separation the stats block had. */
.rw-sec .et-doctor__more {
  margin-top: clamp(14px, 1.6vw, 20px);
}
/* With the stats gone the right column is markedly shorter than the left, and
   the row is top-aligned (see section 16), which left a tall empty area beside
   the copy. Centring the two columns against each other closes it without
   stretching anything. */
/* Compound, not descendant: .et-doctor sits ON the .rw-sec element itself, so
   `.rw-sec .et-doctor` matches nothing at all. */
.rw-sec.et-doctor .row--split-media {
  align-items: center;
}

/* Designer houses: an infinite marquee, no pills.
   REVISION 6 (client: "remove the logos from the pills, I want them floating
   and scrolling in an infinite carousel loop"). The pill was revision 4's
   answer to a readability complaint that turned out to be about a different
   element entirely; with the logos floating, the only thing carrying them is
   the band behind, and all seven wordmarks are pure black ink on transparent,
   so they read on it.

   Every one of these selectors is scoped with .rw-sec on purpose. layout.css
   sets .ethc-houses to display:grid with repeat(7,1fr) -- and to repeat(4) and
   repeat(3) inside media queries -- at :where(.rw-sec) specificity (0,1,0). A
   media query adds no specificity, so (0,2,0) here beats all three at every
   width; the bare class would lose to them and the track would be laid out as
   a grid. */
.rw-sec .ethc-houses.ethc-marquee {
  display: block;
  grid-template-columns: none;
  position: relative;
  width: 100%;
  overflow: hidden;
  /* the ends fade rather than cut, so items enter and leave instead of popping */
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 7%, #000 93%, transparent 100%);
          mask-image: linear-gradient(90deg, transparent 0, #000 7%, #000 93%, transparent 100%);
}
.rw-sec .ethc-marquee__track {
  --ethc-gap: clamp(36px, 5vw, 76px);
  display: flex;
  align-items: center;
  flex-wrap: nowrap;
  width: max-content;
  animation: ethc-marquee-scroll 32s linear infinite;
  will-change: transform;
}
/* The travel is 100%/copies, which is exactly one set. That is only true
   because the spacing is a MARGIN on each item rather than a flex gap: with a
   gap, the track would be (copies x set) + (copies x items - 1) gaps, one gap
   short of a whole number of periods, and the loop would jump by half a gap on
   every wrap. As a margin, each item carries its own trailing space and the
   track is exactly copies x period. */
@keyframes ethc-marquee-scroll {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(calc(-100% / var(--ethc-copies, 3)), 0, 0); }
}
.rw-sec .ethc-marquee .ethc-house {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  margin-inline-end: var(--ethc-gap);
  /* the pill, removed */
  min-height: 0;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: none;
  box-shadow: none;
  -webkit-backdrop-filter: none;
          backdrop-filter: none;
  transform: none;
}
/* The wordmark is an <img>, and components.css lists .ethc-house__logo with the photo frames
   (audit/redesign-brief.json filed it under mediaFrames), so every logo carried a photograph's
   rim: a 32px radius, a 1px border, the glass shadow and overflow:hidden. With overflow:hidden
   that radius trims the image itself, and at 24-32px tall it is a full pill: it cut 0.6-7.7% of
   each logo's ink (Lindberg's L and its glasses mark, the O of Oliver Peoples) and drew a faint
   frame round every one. A logo is not a photo, so the rim comes off here. components.css is
   generated and then post-processed, so it is not edited; .rw-sec outranks its bare class. */
.rw-sec .ethc-house__logo {
  border: 0;
  border-radius: 0;
  box-shadow: none;
}
.rw-sec .ethc-marquee .ethc-house__logo {
  height: clamp(24px, 2.5vw, 32px);
  width: auto;
  max-width: none;
  object-fit: contain;
  display: block;
  /* black artwork on a pale band: held just off full black so the row reads as
     one calm line rather than seven competing logos */
  opacity: .66;
  filter: grayscale(1);
  transition: opacity var(--t-mid) var(--ease);
}
.rw-sec .ethc-marquee:hover .ethc-house__logo { opacity: .9; }
/* a marquee that will not stop is hard to read a single logo in */
.rw-sec .ethc-marquee:hover .ethc-marquee__track,
.rw-sec .ethc-marquee:focus-within .ethc-marquee__track { animation-play-state: paused; }

.surface-dark .ethc-marquee .ethc-house__logo {
  filter: grayscale(1) invert(1);
  opacity: .8;
}

/* Perpetual motion is exactly what this setting is for. Reduced motion gets the
   same row, stopped, and scrollable by hand instead. */
@media (prefers-reduced-motion: reduce) {
  .rw-sec .ethc-marquee__track { animation: none; }
  .rw-sec .ethc-houses.ethc-marquee {
    overflow-x: auto;
    -webkit-mask-image: none;
            mask-image: none;
  }
}

/* --- d · the pull-quote portrait ------------------------------------------
   Until revision 16 this held the background-removed cut-out that sat beside
   the "In Dr. Hyder's words" quote (.ethc-stance--split). The section now
   shows the edited photograph as a photo panel, and its rules are §26. */

/* =========================================================================
   19 · TEXT SITTING ON A PHOTOGRAPH
   =========================================================================
   REVISION 5. The client reported the text on the "Designer houses we carry"
   images as unreadable. Revision 4 treated the brand LOGOS, which was the
   wrong element: sampling their pixels shows all seven are pure black ink on
   transparent (avg luminance 0) over an 82%-white pill, which is legible.

   The unreadable text is the CATEGORY TILES below them. Each tile stacks a
   photograph (.et-cat__scene), a scrim (.et-cat__scrim) and a caption
   (.et-cat__body) — and strip-visuals.mjs had removed the scrim's gradient as
   an appearance declaration without anything re-authoring it. The scrim was
   painting nothing, leaving dark ink on dark photographs. Measured on the
   homepage before this rule:

     Contact Lenses  #17262b on rgb(8,43,30)     1.02:1
     Sunglasses      #17262b on rgb(64,35,19)    1.09:1
     Frames          #17262b on rgb(126,75,41)   2.17:1
     Kids' Eyewear   #17262b on rgb(235,199,150) 9.75:1   (passed only by luck
                                                           of a pale photo)

   32 tiles across the build were in this state. */
.et-cat__scene img,
.et-cat__scene picture {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.et-cat__scrim {
  z-index: 1;
  pointer-events: none;
  background: linear-gradient(to top,
    color-mix(in srgb, var(--c-3) 93%, transparent) 0%,
    color-mix(in srgb, var(--c-3) 84%, transparent) 24%,
    color-mix(in srgb, var(--c-3) 55%, transparent) 48%,
    color-mix(in srgb, var(--c-3) 20%, transparent) 72%,
    transparent 100%);
}
/* The caption has to clear the scrim, and its colour can no longer be
   inherited: the tile's own glass surface is light, so the inherited ink was
   the dark --g-fg. On the scrim the caption is always on-dark. */
.et-cat__body { z-index: 2; }
.rw-sec .et-cat__name,
.rw-sec .et-cat .et-cat__name { color: var(--g-on-dark); }
.rw-sec .et-cat__eyebrow,
.rw-sec .surface-dark .et-cat__eyebrow { color: var(--c-9); }
.rw-sec .et-cat__arrow,
.rw-sec .surface-dark .et-cat__arrow { color: var(--c-9); }
.rw-sec .et-cat__arrow:hover,
.rw-sec .surface-dark .et-cat__arrow:hover { color: var(--c-1); }
/* The photograph covers the tile's glass entirely, so the rim is the only part
   of that surface still doing work. Keep it; drop the blur, which costs a
   composite layer for something no longer visible. */
.et-cat { -webkit-backdrop-filter: none; backdrop-filter: none; }

/* The tile scrim alone is not enough when the caption wraps: a long eyebrow
   pushes the text up the tile to where the gradient has thinned out, and it
   was measured at 2.84:1 on the three-line captions on /products/contact-
   lenses/. A plate that sizes itself to the caption fixes every caption height
   rather than the one the ramp was tuned for. It extends 64px above the
   caption box and fades out there, so there is no visible band edge.
   .et-cat__body is already absolutely positioned, so it is its own containing
   block; isolate it so the plate can sit behind the text but still above the
   tile scrim. */
.et-cat__body { isolation: isolate; }
.et-cat__body::before {
  content: "";
  position: absolute;
  inset: -64px 0 0 0;
  z-index: -1;
  pointer-events: none;
  background: linear-gradient(to top,
    color-mix(in srgb, var(--c-3) 90%, transparent) 0%,
    color-mix(in srgb, var(--c-3) 86%, transparent) calc(100% - 64px),
    transparent 100%);
}

/* --- the sub-page hero -----------------------------------------------------
   .ha-hero__scrim is the same defect as .et-cat__scrim: the element is in the
   markup and layout.css gives it inset:0 and z-index:1, but its gradient was
   stripped as an appearance declaration and never re-authored, so it painted
   nothing. The copy sits left (.ha-hero__copy is max-width:44rem), so the ramp
   is horizontal, with a bottom lift for the sub-heading. Held at 0.86 out to
   40% because the copy column reaches about 52% of the stage at 1440px. */
.ha-hero__scrim {
  background:
    linear-gradient(90deg,
      color-mix(in srgb, var(--c-3) 90%, transparent) 0%,
      color-mix(in srgb, var(--c-3) 86%, transparent) 40%,
      color-mix(in srgb, var(--c-3) 70%, transparent) 58%,
      color-mix(in srgb, var(--c-3) 40%, transparent) 78%,
      color-mix(in srgb, var(--c-3) 18%, transparent) 100%),
    linear-gradient(to top,
      color-mix(in srgb, var(--c-3) 45%, transparent) 0%,
      color-mix(in srgb, var(--c-3) 16%, transparent) 45%,
      transparent 80%);
}
/* Narrow viewports put the copy across the full width, so there is no "cool"
   side of the image to fade towards - the scrim has to be even instead. */
@media (max-width: 860px) {
  .ha-hero__scrim {
    background: linear-gradient(to top,
      color-mix(in srgb, var(--c-3) 90%, transparent) 0%,
      color-mix(in srgb, var(--c-3) 84%, transparent) 45%,
      color-mix(in srgb, var(--c-3) 74%, transparent) 100%);
  }
}

/* --- captions and tags laid directly on a photograph -----------------------
   .et-frame__tag and .tib-creed__cap are positioned over the top-left and
   bottom-left of a photograph with no scrim of any kind behind them, measured
   at 1.35:1 and 1.11:1. A gradient cannot help a chip that small, so each gets
   its own plate. --c-7 on an 82% --c-3 plate is 8.9:1 even over a white
   photograph. */
.et-frame__tag,
.tib-creed__cap {
  display: inline-flex;
  align-items: center;
  padding: .42em .82em;
  border-radius: var(--r-pill);
  background: color-mix(in srgb, var(--c-3) 84%, transparent);
  -webkit-backdrop-filter: blur(10px) saturate(150%);
  backdrop-filter: blur(10px) saturate(150%);
  border: 1px solid color-mix(in srgb, var(--c-1) 20%, transparent);
  box-shadow: 0 10px 24px -12px color-mix(in srgb, var(--c-3) 72%, transparent);
  color: var(--g-on-dark);
  font-weight: 600;
  line-height: 1.25;
  max-width: calc(100% - 24px);
}
.rw-sec .et-frame__tag,
.rw-sec .tib-creed__cap,
.rw-sec .surface-dark .et-frame__tag,
.rw-sec .surface-dark .tib-creed__cap { color: var(--g-on-dark); }

/* The sub-page hero band carries no .surface-dark class, so its copy inherits
   the light-surface ink. That was survivable while .ha-hero__scrim painted
   nothing; now that the scrim is a real dark ramp the copy has to come with
   it, or the heading sits dark-on-dark. Measured at 1.18:1 before this rule. */
/* Scoped with .rw-sec deliberately. The bare class is (0,1,0) and loses to
   `.site-content p` at (0,1,1) in this same stylesheet, which is how
   .ha-hero__sub stayed at --g-fg-soft and measured 1.69:1 on the new scrim
   even though a rule for it existed. */
.rw-sec .ha-hero__inner,
.rw-sec .ha-hero__copy,
.rw-sec .ha-hero__h,
.rw-sec .ha-hero__sub { color: var(--g-on-dark); }
.rw-sec .ha-hero__hl,
.rw-sec .ha-hero__eyebrow,
.rw-sec .ha-hero__call { color: var(--c-9); }
.rw-sec .ha-hero__call:hover { color: var(--c-1); }
.rw-sec .ha-hero__copy .btn-ghost {
  color: var(--g-on-dark);
  border-color: color-mix(in srgb, var(--c-1) 42%, transparent);
}

/* Chips that float directly ON a photograph cannot use the standard 58% glass.
   Every other glass surface sits on a known page background; these sit on
   pixels nobody controls. At 58% a dark photograph shows through and the
   badge's secondary line measured 2.11:1 over the hero. At 93% the plate is
   effectively opaque, which holds 5.4:1 for --g-fg-soft even over a black
   photograph, and the blur still reads as glass against the image edges. */
/* .rw-sec scoping again: components.css assigns the standard glass to these
   at the same specificity and loads after this file, so the bare class loses
   the tie. */
.rw-sec .ethc-hero__badge,
.rw-sec .tib-hero__chip {
  background: color-mix(in srgb, var(--c-1) 93%, transparent);
  -webkit-backdrop-filter: blur(18px) saturate(165%);
  backdrop-filter: blur(18px) saturate(165%);
}

/* =========================================================================
   23 · THE "42 YEARS" BADGES ON DR. HYDER'S PORTRAIT
   =========================================================================
   Four badge families sit on his photograph on 35 pages. When the portrait
   was replaced (revision 12) every one of them was measured against his face
   and against what is behind its text, and all four were wrong:

   · .tib-creed__badge (4 product pages) and .ia-portrait__badge (insurance,
     patient forms): the generated glass block in components.css sets
     position:relative, loads after layout.css's position:absolute at the
     same specificity, and wins - so each rendered as a FULL-WIDTH BAR across
     the top of the frame, over his face (42-94% of it, at every width).
   · .et-doctor__badge (8 pages) and .dc-doctor__badge (21 pages) were never
     glass at all: they are not in components.css's lists, and their own
     backdrop-filter reads the undefined --ds-glass-blur. White text sat on
     the bare photograph: 3.1:1 (worst pixel 1.7) on the old photo, 2.9:1
     (worst 1.09) on the new one.
   · The numeral takes `.site-content b { color: var(--g-fg) }`, dark ink,
     including on the dark plates: 1.4:1 on tib-creed.

   Now: positioned, the standard dark glass that tib-creed already had, a
   light numeral, and the one-line chips (dc-doctor 217px, ia-portrait on
   /patient-forms/ 209px, both missing the <br> the others carry) wrapped to
   two lines, which takes them off his ear at 1440. Measured after, text
   against what is actually behind it: 4.65:1 or better at the worst pixel
   (AA asks 4.5:1), 390 to 1440, 44 readings.

   On a phone the frame becomes a short landscape crop with his face at the
   top centre - exactly under the top-right corner: 80% of his face covered at
   320px, 28% at 390. Below 640px the badges move to the bottom corner, over
   his shirt; tib-creed rides above its name caption. At 320px nothing fits
   between his chin and that caption, so the product badge is hidden below
   360px - each product page states "since 1984" / "42 years" in its text 3
   to 5 times. Face coverage after: 0% for every badge, 320 to 1440. */
.rw-sec .tib-creed__badge,
.rw-sec .ia-portrait__badge { position: absolute; }
.rw-sec .et-doctor__badge,
.rw-sec .dc-doctor__badge {
  background: var(--glassd-bg);
  -webkit-backdrop-filter: var(--glass-blur);
  backdrop-filter: var(--glass-blur);
  border: 1px solid var(--glassd-brd);
  border-radius: var(--r-lg);
  box-shadow: 0 24px 56px -26px color-mix(in srgb, var(--c-3) 60%, transparent), var(--glassd-edge);
}
.rw-sec .et-doctor__badge b,
.rw-sec .dc-doctor__badge b,
.rw-sec .tib-creed__badge b { color: var(--g-on-dark); }
.rw-sec .dc-doctor__badge > span,
.rw-sec .ia-portrait__badge > span { max-width: 5.5em; }
@media (max-width: 639px) {
  .rw-sec .et-doctor__badge,
  .rw-sec .dc-doctor__badge,
  .rw-sec .tib-creed__badge,
  .rw-sec .ia-portrait__badge { top: auto; bottom: 12px; }
  .rw-sec .tib-creed__badge { bottom: 58px; }
}
@media (max-width: 359px) {
  .rw-sec .tib-creed__badge { display: none; }
}

/* =========================================================================
   24 · THE DOCTOR SECTIONS: HIS PHOTOGRAPH AS THE BACKGROUND
   =========================================================================
   Operator, 2026-10-07, on the home page: "make the image you edited a full
   width background image of that section? It looks weird in it's frame".
   2026-10-08: "apply the full-width doctor photo to the other 7 pages" -
   /products/ and six /services/ pages, the other uses of this component.

   Two markups carry it:
   · home: .row--split-media, the photo column FIRST, the text column last;
   · the seven: .row--split, the text column (.et-doctor__story) FIRST, then the
     photo column with the badge, name and role.
   Each shared rule below names both (the home's own selectors are unchanged);
   the rules after them handle the second markup only.

   Desktop (1025px and up, where the two columns sit side by side):
   · The frame's boxes are dissolved (display:contents on the photo column and
     on .et-doctor__media). .et-doctor__portrait - which holds the <picture>
     with the 16:9 version (tools/build.mjs, reshapeDoctor) - covers the whole
     band. It is still inside .container (position:relative, z-index:1), so it
     is pulled out to the section's edges with the full-bleed offsets:
     50% - 50vw sideways, the band's own --et-flow padding up and down. Below
     1200px the bleed is 8px wider than the window; body's overflow-x:hidden
     hides it (HANDOFF, known gaps).
   · object-position puts his face at 27% of the width, over the left column,
     and a gradient in the band's dark --c-3 (::after) darkens the right side
     behind the text. The text is always in the RIGHT column: the 16:9 photo
     has him on the left, and a real person's photograph is not mirrored.
   · What sat under the frame - the "42 years" chip, his name, role and link -
     moves into the right column under the text, so nothing covers him.
   · The seven pages' text column is longer (139-185 words, three chips and
     three stat tiles), and cover scales the photo to the section's height, so
     a taller section draws him larger. Their stat tiles sit in one row instead
     of a stack: that took the section from 1583px to about 1300px at 1440,
     against the home page's 1103px.
   Below 1025px the section stacks, and the frame becomes a full-width band:
   the portrait version, no frame, his face large. On the seven pages the
   photo column is moved first (order:-1), as it comes first on the home page;
   the DOM, and so the reading order, keeps the text first.
   Scoped by .rw-p-home or by the .row--split markup, NOT body.is-homepage:
   layout.css's body.is-homepage rules never match (the home <body> is
   class="pg pg-home"). */
@media (min-width: 1025px) {
  .rw-sec.rw-p-home.et-doctor .row--split-media,
  .rw-sec.et-doctor .row--split {
    row-gap: 0;
    align-content: center;
    min-height: clamp(560px, 44vw, 760px);
  }
  .rw-sec.rw-p-home.et-doctor .row--split-media > .col:first-child,
  .rw-sec.rw-p-home.et-doctor .et-doctor__media,
  .rw-sec.et-doctor .row--split > .col:has(> .et-doctor__media),
  .rw-sec.et-doctor .row--split .et-doctor__media { display: contents; }
  .rw-sec.rw-p-home.et-doctor .row--split-media > .col:last-child,
  .rw-sec.et-doctor .row--split > .et-doctor__story { grid-column: 2; grid-row: 1; }
  .rw-sec.rw-p-home.et-doctor .et-doctor__portrait,
  .rw-sec.et-doctor .row--split .et-doctor__portrait {
    position: absolute;
    top: calc(-1 * var(--et-flow));
    bottom: calc(-1 * var(--et-flow));
    left: calc(50% - 50vw);
    right: calc(50% - 50vw);
    z-index: 0;
  }
  .rw-sec.rw-p-home.et-doctor .et-doctor__portrait img,
  .rw-sec.et-doctor .row--split .et-doctor__portrait img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: 27% 22%;
    transform: none;
  }
  .rw-sec.rw-p-home.et-doctor .et-doctor__portrait::after,
  .rw-sec.et-doctor .row--split .et-doctor__portrait::after {
    content: "";
    background:
      linear-gradient(90deg,
        color-mix(in srgb, var(--c-3) 0%, transparent) 0%,
        color-mix(in srgb, var(--c-3) 0%, transparent) 36%,
        color-mix(in srgb, var(--c-3) 55%, transparent) 46%,
        color-mix(in srgb, var(--c-3) 82%, transparent) 56%,
        color-mix(in srgb, var(--c-3) 88%, transparent) 100%),
      linear-gradient(180deg,
        color-mix(in srgb, var(--c-3) 30%, transparent) 0%,
        transparent 16%,
        transparent 84%,
        color-mix(in srgb, var(--c-3) 40%, transparent) 100%);
  }
  .rw-sec.rw-p-home.et-doctor .et-doctor__badge,
  .rw-sec.rw-p-home.et-doctor .et-doctor__name,
  .rw-sec.rw-p-home.et-doctor .et-doctor__role,
  .rw-sec.et-doctor .row--split .et-doctor__badge,
  .rw-sec.et-doctor .row--split .et-doctor__name,
  .rw-sec.et-doctor .row--split .et-doctor__role {
    grid-column: 2;
    position: relative;
    z-index: 1;
  }
  .rw-sec.rw-p-home.et-doctor .et-doctor__badge,
  .rw-sec.et-doctor .row--split .et-doctor__badge {
    inset: auto;
    justify-self: start;
    margin-top: 32px;
  }
  .rw-sec.rw-p-home.et-doctor .et-doctor__name,
  .rw-sec.et-doctor .row--split .et-doctor__name { margin-top: 16px; }

  /* the seven pages only: the text takes the wider right column, as on the
     home page (layout.css gives .row--split 1.05fr 1fr, text first), and the
     three stat tiles share one row */
  .rw-sec.et-doctor .row--split { grid-template-columns: 1fr 1.05fr; }
  .rw-sec.et-doctor .row--split .et-doctor__stats {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: minmax(0, 1fr);
    gap: 12px;
  }
  .rw-sec.et-doctor .row--split .et-doctor__stats > .et-stat {
    width: auto;
    min-width: 0;
    max-width: none;
    flex: none;
    margin: 0;
    /* narrower tiles: less side padding, so a label does not wrap word by word */
    padding-inline: 16px;
    /* The photo is behind these tiles here, and the 7%-white glass let a light
       patch through: one label's worst pixel fell to 3.58:1 at 1025. A dark
       tint keeps the photo faintly visible and the label steady. */
    background: color-mix(in srgb, var(--c-3) 42%, transparent);
  }
}
/* 1025-1099px: the seven pages' text column starts at 520-558px, and their
   taller sections draw him larger, so at 27% his arm reached 9-17px under the
   first paragraph. 30% moves the photo 30-34px further left: clear of the text,
   for at most 16px of his outer sleeve at the window's left edge at 1025. */
@media (min-width: 1025px) and (max-width: 1099px) {
  .rw-sec.et-doctor .row--split .et-doctor__portrait img { object-position: 30% 22%; }
}
@media (max-width: 1024px) {
  .rw-sec.rw-p-home.et-doctor .et-doctor__media,
  .rw-sec.et-doctor .row--split .et-doctor__media {
    width: auto;
    max-width: none;
    margin-inline: calc(50% - 50vw);
  }
  .rw-sec.et-doctor .row--split > .col:has(> .et-doctor__media) { order: -1; }
}

/* =========================================================================
   25 · THE HOME KIDS SECTION: A FULL-BLEED STILL LIFE, THE TEXT ON GLASS
   =========================================================================
   Operator, 2026-10-07: "redesign this section, enhance the image resolution
   and make it full width too". Home only (.rw-p-home.rw-s5).

   Desktop (1200px and up): the 16:9 still life (tools/build.mjs, KIDS_SWAP)
   covers the band; its three frames sit in the right half, its left half is
   an empty butter-yellow wall over a mint tabletop. This section's container
   is not positioned, so .ethc-media, made absolute, covers the section itself.
   The text sits on that calm left half in a frosted-glass card (white glass,
   the site's --glass-* shadow and edge), and the right column is left empty
   for the glasses. The reveal slide is switched off for the background - a
   26px shift would open a gap at the section's top edge.

   Below 1200px the section stacks - text on the band's cream, then the
   photograph as a full-width 4:3 band, served by <picture> as a crop centred
   on the frames. 1025-1199px is forced to one column here: two columns that
   narrow cannot keep the glasses clear of the card.

   The geometry that keeps the glasses out from under the card: the photo is
   cover-fitted and anchored right (object-position 100%), so the frames'
   left edge always sits 0.676 section-heights in from the right edge (they
   span x 62-95% of the 16:9 image). The section is held near 16:9
   (row min-height 56.25vw minus its 64px top and bottom padding), and the card
   is capped at clamp(480px, 40vw, 600px). Measured clearance between the
   card and the frames: see the change log (revision 14). */
@media (min-width: 1200px) {
  .rw-sec.rw-p-home.rw-s5 { padding-block: 64px; }
  .rw-sec.rw-p-home.rw-s5 .row--split {
    grid-template-columns: minmax(0, clamp(480px, 40vw, 600px)) 1fr;
    align-items: center;
    min-height: calc(56.25vw - 128px);
  }
  .rw-sec.rw-p-home.rw-s5 .ethc-media {
    position: absolute;
    inset: 0;
    z-index: 0;
    width: auto;
    max-height: none;
    aspect-ratio: auto;
    transform: none;
  }
  .rw-sec.rw-p-home.rw-s5 .ethc-media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: 100% 50%;
    transform: none;
  }
  .rw-sec.rw-p-home.rw-s5 .row--split > .col:first-child {
    position: relative;
    z-index: 1;
  }
  .rw-sec.rw-p-home.rw-s5 .row--split > .col:first-child > .et-reveal {
    padding: clamp(28px, 2.6vw, 40px);
    background: color-mix(in srgb, var(--c-1) 64%, transparent);
    -webkit-backdrop-filter: blur(18px) saturate(140%);
    backdrop-filter: blur(18px) saturate(140%);
    border: 1px solid color-mix(in srgb, var(--c-1) 80%, transparent);
    border-radius: var(--r-lg);
    box-shadow: var(--glass-shadow), var(--glass-edge);
  }
}
@media (min-width: 1025px) and (max-width: 1199px) {
  .rw-sec.rw-p-home.rw-s5 .row--split { grid-template-columns: 1fr; }
}
@media (max-width: 1199px) {
  .rw-sec.rw-p-home.rw-s5 .ethc-media {
    width: auto;
    max-width: none;
    margin-inline: calc(50% - 50vw);
    aspect-ratio: 4 / 3;
    max-height: none;
  }
  /* the <source> serves a 4:3 crop centred on the frames at these widths */
  .rw-sec.rw-p-home.rw-s5 .ethc-media img { object-position: 50% 50%; }
}

/* =========================================================================
   26 · THE HOME QUOTE SECTION: HIS WORDS BESIDE HIS PHOTOGRAPH
   =========================================================================
   Operator, 2026-10-07: "let's redesign this section too, I want to use the
   same enhanced photo of dr. jerry hyder in the first section we revised. And
   then put some flare in the text not just plain text in here that's too
   boring". Home page only. tools/build.mjs gives the section the et-quote
   hook, puts the edited portrait in a figure that is a DIRECT child of the
   section (not of the quote block, whose blur-in reveal would otherwise become
   the photo's containing block mid-animation), and wraps four phrases of the
   quote in accent spans without changing a word.

   · Phones and tablets (the base rules): the photo is a full-width band at
     the top of the section, its bottom masked into the band, and the quote
     follows.
   · 1025px and up: the photo is a panel on the right 45% of the section, full
     height, cover-cropped on his face. A mask fades its left edge into the
     band, so the band's own gradients show through rather than a colour that
     would never match them. The quote takes the left and ends 40-80px short of
     the panel. The section is held at 52vw (600-860px), the text centred in it.
     Mobile-first on purpose: a max-width:1024px / min-width:1025px pair leaves
     zoomed widths between the two (1/64px steps) with neither rule, and there
     the photo would fall back to its full 1100px-tall intrinsic box.
   · The type: the quote in the display face at 25-40px; an oversized
     teal-to-gold opening mark (the display face's own "66", drawn by ::before,
     so not text); "relationship" in gold Instrument Serif italic (the one new
     face, requested on the home page only); gold-to-teal underlines under
     "30 unhurried minutes," and "42 years." that draw in when the block
     reveals and stop short of the comma and the full stop; "big-box counter."
     kept on one line (it broke at the hyphen); the name under a gradient rule.
   · Reduced motion: §14 makes every transition instant and shows every
     reveal, so the underlines and the photo arrive in their final state. */
.rw-sec.et-quote { padding-top: 0; }
.rw-sec.et-quote .row--head { margin-bottom: 0; }
.rw-sec.et-quote .col--measure { max-width: none; }
.rw-sec.et-quote .ethc-stance { text-align: left; }
.rw-sec.et-quote .et-eyebrow { justify-content: flex-start; text-align: left; }

.rw-sec.et-quote .ethc-stance__photo {
  position: relative;
  z-index: 0;
  height: clamp(340px, 92vw, 600px);
  margin: 0 0 clamp(18px, 4vw, 34px);
  overflow: hidden;
  -webkit-mask-image: linear-gradient(180deg, #000 68%, transparent 100%);
          mask-image: linear-gradient(180deg, #000 68%, transparent 100%);
}
.rw-sec.et-quote .ethc-stance__photo img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 14%;
  /* settles in from 106% as the photo reveals */
  transform: scale(1.06);
  transition: transform 1.8s var(--ease);
}
.rw-sec.et-quote .ethc-stance__photo.in-view img { transform: none; }
/* the global reveal fades, lifts and blurs; a photo panel only fades */
.rw-sec.et-quote .ethc-stance__photo.reveal { transform: none; filter: none; }

.rw-sec.et-quote .ethc-stance__q {
  position: relative;
  max-width: none;
  margin: clamp(14px, 1.6vw, 22px) 0 0;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(25px, 1.15vw + 17px, 40px);
  line-height: 1.22;
  letter-spacing: -.018em;
  color: color-mix(in srgb, var(--c-1) 88%, transparent);
  text-align: left;
  text-wrap: pretty;
}
.rw-sec.et-quote .ethc-stance__q::before {
  content: "\201C";
  display: block;
  width: fit-content;            /* so the gradient spans the glyph, not the line */
  height: .44em;
  margin: 0 0 .1em -.05em;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(120px, 9vw, 176px);
  line-height: .9;
  background: linear-gradient(115deg, var(--g-teal-lit) 8%, var(--g-gold-lit) 62%, var(--g-gold) 100%);
  -webkit-background-clip: text;
          background-clip: text;
  color: transparent;
}
.rw-sec.et-quote .ethc-stance__word {
  font-family: 'Instrument Serif', Georgia, 'Times New Roman', serif;
  font-style: italic;
  font-weight: 400;
  font-size: 1.22em;
  line-height: 1;
  letter-spacing: 0;
  padding-inline-end: .06em;     /* keeps the italic's overhang inside the clip */
  background: linear-gradient(100deg, var(--g-gold-lit) 20%, var(--g-gold) 90%);
  -webkit-background-clip: text;
          background-clip: text;
  color: transparent;
}
.rw-sec.et-quote .ethc-stance__fact {
  color: var(--c-1);
  font-weight: 600;
  background-image: linear-gradient(90deg, var(--g-gold), var(--g-teal-lit));
  background-repeat: no-repeat;
  background-position: 0 96%;
  /* the span ends on its comma or full stop (build.mjs); the line stops .32em short of it */
  background-size: calc(100% - .32em) .085em;
  padding-bottom: .05em;
  transition: background-size 1.1s var(--ease) .55s;
}
.rw-sec.et-quote .ethc-stance__fact + .ethc-stance__fact { transition-delay: .85s; }
.rw-sec.et-quote .reveal:not(.in-view) .ethc-stance__fact { background-size: 0 .085em; }
.rw-sec.et-quote .ethc-stance__keep { white-space: nowrap; }
.rw-sec.et-quote .ethc-stance__by {
  margin-top: clamp(22px, 2.4vw, 34px);
  gap: .85em;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(17px, .45vw + 12px, 21px);
  letter-spacing: .01em;
  color: var(--c-1);
}
.rw-sec.et-quote .ethc-stance__by::before {
  content: "";
  width: 48px;
  height: 2px;
  border-radius: 2px;
  background: linear-gradient(90deg, var(--g-gold), var(--g-teal-lit));
}

@media (min-width: 1025px) {
  .rw-sec.et-quote {
    display: grid;
    align-content: center;
    min-height: clamp(600px, 52vw, 860px);
    padding-top: var(--et-flow);
  }
  .rw-sec.et-quote .ethc-stance__photo {
    position: absolute;
    top: 0;
    bottom: 0;
    right: 0;
    width: 45%;
    height: auto;
    margin: 0;
    -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 17%);
            mask-image: linear-gradient(90deg, transparent 0, #000 17%);
  }
  /* The panel starts 5vw right of the container's centre line (it is 45% of a
     section the container is centred in), so the column ends that far past
     the middle, less a 40-80px gap. */
  .rw-sec.et-quote .ethc-stance__body { max-width: calc(50% + 5vw - clamp(40px, 4.4vw, 80px)); }
}

/* =========================================================================
   27 · WIDE SCREENS: THE LAYOUT GROWS WITH THE WINDOW
   =========================================================================
   Operator, 2026-10-08: "I want the elements of the whole site to be
   responsive to all screen sizes. The problem is when it is viewed in a wider
   screen size, the elements are too compressed that it leaves a huge space/gap
   on the sides and in correlation to other elements."

   Measured before this section: every page's content was 1100px wide at any
   window, leaving 163px of empty margin per side at 1440, 403px at 1920 and
   723px at 2560, and nothing else grew either (type, gaps, section padding).

   The design was tuned at 1280-1440, so everything here is inside one
   min-width:1441px query: at 1440 and below nothing can change. Above it,
   each value grows in a straight line from its 1440 value, at
   (window - 1440px) x k, and stops at its target for a 2560px window
   (--wx = window - 1440px, so --wx is 1120px at 2560):
     container 1180 -> 1920px (content 1100 -> 1784px, about 70-75% of the
     window, as at 1440); side padding 40 -> 68; section padding 108 -> 160;
     grid gaps 30 -> 46; the --ds-space scale x1.33; body text 17 -> 19.5px
     and every other type size about x1.15, so a wider card holds larger type
     rather than the same small type spread thinner. Lines of text stay
     readable: the measured characters-per-line are re-checked at 1920 and
     2560. Images get two more `sizes` buckets (tools/build.mjs) so the larger
     renders still load a sharp enough file. */
@media (min-width: 1441px) {
  :root {
    --wx: calc(100vw - 1440px);
    /* layout */
    --wrap: min(1920px, calc(1180px + var(--wx) * 0.66));
    --gutter: min(68px, calc(40px + var(--wx) * 0.025));
    --flow: min(160px, calc(108px + var(--wx) * 0.0464));
    --et-gap: min(46px, calc(30px + var(--wx) * 0.0143));
    --ds-space-2xs: min(5px, calc(4px + var(--wx) * 0.0009));
    --ds-space-xs: min(10.5px, calc(8px + var(--wx) * 0.0022));
    --ds-space-sm: min(18.5px, calc(14px + var(--wx) * 0.004));
    --ds-space-md: min(32px, calc(24px + var(--wx) * 0.0071));
    --ds-space-lg: min(53px, calc(40px + var(--wx) * 0.0116));
    --ds-space-xl: min(85px, calc(64px + var(--wx) * 0.0188));
    --ds-space-2xl: min(128px, calc(96px + var(--wx) * 0.0286));
    /* the five size tokens the header, footer, labels and links use (font-size only) */
    --fs-6: min(14px, calc(12.48px + var(--wx) * 0.00136));
    --fs-8: min(14.75px, calc(13px + var(--wx) * 0.00156));
    --fs-16: min(16.5px, calc(14.5px + var(--wx) * 0.00179));
    --fs-19: min(17px, calc(15px + var(--wx) * 0.00179));
    --fs-23: min(18.25px, calc(16px + var(--wx) * 0.002));
  }

  /* --- type in system.css (later in the same file wins at equal weight) --- */
  body { font-size: min(19.5px, calc(17px + var(--wx) * 0.00223)); }
  h1, .et-h1, .ethc-hero__h { font-size: clamp(36px, 5.1vw, min(80px, calc(68px + var(--wx) * 0.0107))); }
  h2, .et-h2 { font-size: clamp(27px, 3.5vw, min(53px, calc(45px + var(--wx) * 0.0071))); }
  h3, .et-h3 { font-size: clamp(19px, 1.9vw, min(28px, calc(24px + var(--wx) * 0.0036))); }
  h4 { font-size: clamp(17px, 1.6vw, min(23px, calc(20px + var(--wx) * 0.0027))); }
  .et-lede, .dc-lead, .lede, .ha-hero__lede, .tib-hero__lede, .od-hero__lede {
    font-size: clamp(17px, 1.35vw, min(22.5px, calc(19.5px + var(--wx) * 0.0027)));
  }
  .et-eyebrow, .eyebrow, .ha-eyebrow, .tib-eyebrow, .od-eyebrow, .dc-eyebrow { font-size: min(13px, calc(11.5px + var(--wx) * 0.00134)); }
  .btn { font-size: min(17.5px, calc(15.5px + var(--wx) * 0.00179)); }
  .btn-lg { font-size: min(18.75px, calc(16.5px + var(--wx) * 0.002)); }
  .dc-faq__q, .dc-faq__item > summary { font-size: min(20px, calc(17.5px + var(--wx) * 0.00223)); }
  blockquote, .et-review__q, .bw-quote { font-size: clamp(19px, 2vw, min(28px, calc(24px + var(--wx) * 0.0036))); }
  .et-review__src, .bw-quote__src { font-size: min(15.5px, calc(13.5px + var(--wx) * 0.00179)); }
  .ethc-hero .ethc-hero__sub { font-size: clamp(17px, 1.4vw, min(23px, calc(20px + var(--wx) * 0.0027))); }
  .rw-sec.ethc-hero .ethc-hero__k { font-size: clamp(19px, 5.6vw, min(29px, calc(25px + var(--wx) * 0.0036))); }
  .rw-sec.ethc-hero .ethc-hero__l { font-size: min(11px, calc(9.5px + var(--wx) * 0.00134)); }
  .rw-sec.et-quote .ethc-stance__q { font-size: clamp(25px, 1.15vw + 17px, min(46px, calc(40px + var(--wx) * 0.0054))); }
  .rw-sec.et-quote .ethc-stance__q::before { font-size: clamp(120px, 9vw, min(204px, calc(176px + var(--wx) * 0.025))); }
  .rw-sec.et-quote .ethc-stance__by { font-size: clamp(17px, .45vw + 12px, min(24px, calc(21px + var(--wx) * 0.0027))); }

  /* --- type set in components.css and chrome.css, which load after this file:
         the html prefix gives each override one more element of weight --- */
  html :is(.et-pill, .et-dot, .ethc-plan, .ethc-menu__chip, .ethc-point, .tib-point, .tib-chip, .ct-find__tag) {
    font-size: min(15.5px, calc(13.5px + var(--wx) * 0.00179));
  }
  html :is(.dc-proof__k, .ethc-stat__k, .ethc-hero__k, .ia-stat__k, .bw-timeline__year) {
    font-size: clamp(30px, 3.6vw, min(54px, calc(46px + var(--wx) * 0.0071)));
  }
  html .rw-sec.ethc-hero .ethc-hero__k { font-size: clamp(19px, 5.6vw, min(29px, calc(25px + var(--wx) * 0.0036))); }
  html :is(.et-eyebrow, .dc-pill__n, .ethc-why__tag, .tib-collection__num, .ha-ins__lead, .ha-hero__eyebrow, .od-quote__role, .ia-callout__k, .bw-toc__title, .bw-manifesto__idx) {
    font-size: min(13px, calc(11.5px + var(--wx) * 0.00134));
  }
  html .mega-promo h3 { font-size: min(23px, calc(20px + var(--wx) * 0.0027)); }
  html :is(.mega-promo p, .mega-promo .btn) { font-size: min(16px, calc(14px + var(--wx) * 0.00179)); }
  html .mlink { font-size: min(15.5px, calc(13.5px + var(--wx) * 0.00179)); }
  html .search-panel__h { font-size: min(19.5px, calc(17px + var(--wx) * 0.00223)); }
  html :is(.book-meta, .form-note, .foot-blurb, .foot-col a, .foot-addr) { font-size: min(16px, calc(14px + var(--wx) * 0.00179)); }
  html .search-hit__t { font-size: min(21px, calc(18.5px + var(--wx) * 0.00223)); }
  html .search-hit__u { font-size: min(13.75px, calc(12px + var(--wx) * 0.00156)); }
  html .foot-name { font-size: min(30px, calc(26px + var(--wx) * 0.0036)); }
  html .foot-h { font-size: min(13px, calc(11.5px + var(--wx) * 0.00134)); }
  html .foot-phone { font-size: min(18.75px, calc(16.5px + var(--wx) * 0.002)) !important; }
  html .brand img { height: min(44px, calc(38px + var(--wx) * 0.0054)); max-width: min(220px, calc(190px + var(--wx) * 0.0268)); }
  html .site-head.is-stuck .brand img { height: min(37px, calc(32px + var(--wx) * 0.0045)); }

  /* --- components sized in px that should keep their share of the width --- */
  /* the designer-house logos (revision 15) */
  .rw-sec .ethc-marquee .ethc-house__logo { height: clamp(24px, 2.5vw, min(40px, calc(32px + var(--wx) * 0.0071))); }
  /* the home kids section's glass card (revision 14): the frames stay clear,
     their left edge is 0.676 section-heights from the right edge (>= 370px at 2560) */
  .rw-sec.rw-p-home.rw-s5 .row--split { grid-template-columns: minmax(0, min(820px, calc(600px + var(--wx) * 0.196))) 1fr; }
  /* the home quote section (revision 16) keeps its proportion of the window */
  .rw-sec.et-quote { min-height: clamp(600px, 52vw, min(1100px, calc(860px + var(--wx) * 0.214))); }

  /* layout.css declares its spacing scale and a 1200px --ds-container-max on
     EVERY section (:where(.rw-sec), weight 0), so the :root values above never
     reach inside a section: the service pages' hero copy stayed in a 1200px
     box and started 401px from the left at 1920 while the content below
     started at 256. Declared again at the section's own level. */
  .rw-sec {
    --ds-container-max: var(--wrap);
    --ds-section-py: min(160px, calc(110px + var(--wx) * 0.0446));
    --ds-space-2xs: min(5px, calc(4px + var(--wx) * 0.0009));
    --ds-space-xs: min(10.5px, calc(8px + var(--wx) * 0.0022));
    --ds-space-sm: min(18.5px, calc(14px + var(--wx) * 0.004));
    --ds-space-md: min(32px, calc(24px + var(--wx) * 0.0071));
    --ds-space-lg: min(53px, calc(40px + var(--wx) * 0.0116));
    --ds-space-xl: min(85px, calc(64px + var(--wx) * 0.0188));
    --ds-space-2xl: min(128px, calc(96px + var(--wx) * 0.0286));
  }
  /* the hero's own side padding, matched to the container's, so its copy
     starts on the same line as every section below it */
  .rw-sec .ha-hero__inner { padding-inline: var(--gutter); }

  /* --- reading measure. The columns grow faster than the type (about x1.6
     against x1.15), so unchecked a paragraph ran to 80-100 characters a line
     at 2560 (99 sections, measured). Caps are in em, so they follow the text
     size: about 70 characters for running text, 63 for ledes, 56 for the large
     quotes. Running text gets its cap at weight 0, so any rule that already
     sets a width keeps it; where an existing cap is known, the new one is the
     smaller of the two, so nothing is made wider. --- */
  :where(.rw-sec) :where(p, li, dd) { max-width: 35em; }
  .rw-sec .et-lede { max-width: min(52rem, 34em); }
  .rw-sec .et-sec-head--split .et-lede { max-width: min(34rem, 34em); }
  .rw-sec .dc-lead { max-width: 33em; }
  .rw-sec .dc-faq__a { max-width: min(54rem, 35em); }
  .rw-sec .bw-timeline__d { max-width: 35em; }
  .rw-sec :is(.tib-creed__q, .et-review__q) { max-width: 30em; }

  /* --- three boxes layout.css fixes in px that are layouts, not text, so at
     1920 they sat in the left two thirds of the container: the "what we stand
     on" rows (.bw-manifesto, 1180px), the bio card (.od-bio, 960px) and the
     story timeline (.bw-timeline, 780px). They keep the share of the
     container they had at 1440 (1180, 960 and 780 of 1180). --- */
  .rw-sec .bw-manifesto { max-width: var(--wrap); }
  .rw-sec .od-bio { max-width: calc(var(--wrap) * 0.8136); }
  .rw-sec .bw-timeline { max-width: calc(var(--wrap) * 0.661); }
}

/* =========================================================================
   28 · INTERNAL PAGE HEROES: SHORTER, AND SPREAD ACROSS THE WIDTH
   =========================================================================
   Operator, 2026-10-09: "the hero section for internal pages need to be
   fixed, because in wide screen it looks awkward with a heavy text on the
   left and huge vacant realty space on the right. ... make those sections
   shorter too and evenly spread out the text to balance the look."

   Measured before (1920x1080): the photo-card hero (.ha-hero, six /services/
   pages) held its copy in the left 37% of the card, with 945px of photo to
   its right, and was 1115-1330px tall; the framed-photo hero (.dc-hero, 21
   service pages) was 1243-1724px tall with a 4-8 line heading; the visit
   page's hero (.ct-hero) left its right 55% empty. At 1280x585 they were
   988-1113, 1303-1677 and 914px tall.

   · Every internal page's first section starts closer to the header, and
     every internal hero heading shares one size, about 26% below the
     site-wide h1 (the home page keeps its own hero).
   · .ha-hero: from 1025px the copy is two columns inside the card, eyebrow
     and heading on the left (.ha-hero__lead), the paragraph and the two
     calls to action on the right (.ha-hero__side, both wrappers added by
     tools/build.mjs), the two blocks centred on each other. The card shows
     the generated gallery image (tools/build.mjs, INNER_HERO) under a
     darker, even scrim, because text now sits on both halves.
   · .dc-hero: from 1025px the heading runs across the top; the paragraph and
     buttons share the row below with the photo, which now stretches to
     their height; the three proof tiles take one full-width row. The badge
     on the photo (.dc-chip) had no surface at all (layout.css gives it no
     background, and its blur reads the undefined --ds-glass-blur), so its
     text sat directly on the photo; it gets the glass tile's surface at
     every width.
   · .ct-hero: from 1025px the three facts stand as glass tiles in a right-
     hand column beside the copy instead of a row below it.
   Below 1025px the stacked layouts are unchanged apart from the top
   spacing (and the photo card's bottom spacing), the heading size on
   tablets, the badge's surface and the gap after the first paragraph on
   /services/adult-eye-exams/. */
body:not(.pg-home) main > .rw-sec:first-child { padding-top: var(--hero-top, clamp(36px, 3.6vw, 52px)); }
.rw-sec :is(.ha-hero__h, .dc-hero__h, .ct-hero__h, .tib-hero__h, .et-hero__h, .bw-founder__h, .et-h1) {
  font-size: clamp(36px, 3.5vw, 50.4px);
}
@media (min-width: 1441px) {
  body:not(.pg-home) main > .rw-sec:first-child {
    --hero-top-wide: min(64px, calc(52px + var(--wx) * 0.0107));
    padding-top: var(--hero-top, var(--hero-top-wide));
  }
  .rw-sec :is(.ha-hero__h, .dc-hero__h, .ct-hero__h, .tib-hero__h, .et-hero__h, .bw-founder__h, .et-h1) {
    font-size: min(62px, calc(50.4px + var(--wx) * 0.0104));
  }
}

/* --- the photo-card hero --- */
.rw-sec.ha-hero { --hero-top: clamp(20px, 1.6vw, 32px); padding-bottom: clamp(40px, 4.4vw, 72px); }
@media (min-width: 1025px) {
  .rw-sec.ha-hero .ha-hero__stage { min-height: 0; }
  .rw-sec.ha-hero .ha-hero__inner { padding-block: clamp(40px, 3.6vw, 76px); }
  /* Two blocks, centred on each other: on these six pages the paragraph
     block is usually the taller one, and with the four children as separate
     grid items (top-aligned on shared rows) the heading column ended 168-224px
     short of the buttons at 1025 and 18-107px at 1920. */
  .rw-sec.ha-hero .ha-hero__copy {
    max-width: none;
    display: grid;
    grid-template-columns: minmax(0, 1.08fr) minmax(0, 1fr);
    column-gap: clamp(48px, 5.5vw, 108px);
    align-items: center;
  }
  .rw-sec.ha-hero .ha-hero__h { margin-top: var(--ds-space-sm); }
  .rw-sec.ha-hero .ha-hero__sub { max-width: 36em; margin-top: 0; }
}
/* The scrim is even across the card wherever the old one ran from dark to
   clear (861px and up): from 1025px text sits on both halves, and at 861-1024
   the stacked copy is up to 44rem wide, 70-85% of the card, so its right end
   sat on the old scrim's lightest part (the highlighted words' worst pixel
   measured 2.55:1 there with the new photo). */
@media (min-width: 861px) {
  .rw-sec.ha-hero .ha-hero__scrim {
    background:
      linear-gradient(90deg,
        color-mix(in srgb, var(--c-3) 78%, transparent) 0%,
        color-mix(in srgb, var(--c-3) 66%, transparent) 46%,
        color-mix(in srgb, var(--c-3) 62%, transparent) 54%,
        color-mix(in srgb, var(--c-3) 72%, transparent) 100%),
      linear-gradient(to top, color-mix(in srgb, var(--c-3) 36%, transparent) 0%, transparent 60%),
      linear-gradient(to bottom, color-mix(in srgb, var(--c-3) 32%, transparent) 0%, transparent 40%);
  }
}
/* Where the window is narrow it is often short as well (the operator's
   1280x585). The paragraph block is the taller one on every page there, so it
   gets the wider share and the card a little less padding. At 1280x585 the six
   cards end at 475-547px (501-585 without this) and the two blocks differ by
   3-72px in height (25-100); at 1100, 58-127 (99-196). Above 1366 the heading
   keeps the wider share: carried on to 1440 this made the cards taller there
   (up to 473px against 454). The cards change height by up to 39px between
   1366 and 1367. */
@media (min-width: 1025px) and (max-width: 1366px) {
  .rw-sec.ha-hero .ha-hero__copy { grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr); }
  .rw-sec.ha-hero .ha-hero__inner { padding-block: clamp(40px, 3.2vw, 76px); }
}

/* --- the framed-photo hero --- */
.rw-sec .dc-chip {
  background: var(--glass-bg-2);
  border: 1px solid var(--glass-brd);
  border-radius: var(--r-md);
  box-shadow: var(--glass-shadow);
  -webkit-backdrop-filter: var(--glass-blur);
          backdrop-filter: var(--glass-blur);
}
@media (min-width: 1025px) {
  /* The copy's own boxes step aside (display: contents), so its children
     join the row's grid: eyebrow and heading across both columns (rows 1-2),
     the one or two paragraphs and the buttons in the left column (rows 3-5),
     the proof tiles across both (row 6), the photo on the right (rows 3-5). */
  .rw-sec.dc-hero .row--split {
    grid-template-columns: minmax(0, 1.08fr) minmax(0, 1fr);
    grid-template-rows: repeat(6, auto);
    column-gap: clamp(48px, 5.5vw, 108px);
    row-gap: 0;
    align-items: start;
  }
  .rw-sec.dc-hero .row--split > .col:first-child,
  .rw-sec.dc-hero .dc-hero__copy { display: contents; }
  .rw-sec.dc-hero .dc-hero__copy > * { grid-column: 1; }
  .rw-sec.dc-hero .dc-hero__copy > .et-eyebrow { grid-column: 1 / -1; grid-row: 1; }
  /* text-wrap: pretty, not the site's balance: a balanced two-line heading
     stopped at 864 of its 1426px at 2560, leaving the top right empty; pretty
     fills the first line and still avoids a one-word last line */
  .rw-sec.dc-hero .dc-hero__copy > .dc-hero__h { grid-column: 1 / -1; grid-row: 2; max-width: 23em; margin-bottom: clamp(24px, 2.6vw, 44px); text-wrap: pretty; }
  .rw-sec.dc-hero .dc-hero__h + * { margin-top: 0; }
  .rw-sec.dc-hero .dc-hero__copy > .dc-proof { grid-column: 1 / -1; grid-row: 6; }
  .rw-sec.dc-hero .row--split > .col:last-child { grid-column: 2; grid-row: 3 / 6; align-self: stretch; display: flex; flex-direction: column; }
  .rw-sec.dc-hero .dc-hero__media { flex: 1 1 auto; display: flex; flex-direction: column; }
  /* the floor keeps a very short text block from flattening the photo; 240px
     sits under the shortest measured block (254px), so the photo never runs
     past the buttons */
  .rw-sec.dc-hero .dc-frame--tall { flex: 1 1 auto; aspect-ratio: auto; height: auto; max-height: none; min-height: 240px; }
  .rw-sec.dc-hero .dc-proof { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: clamp(12px, 1.2vw, 20px); margin-top: clamp(32px, 3.2vw, 52px); padding-top: 0; }
  .rw-sec.dc-hero .dc-proof__k { font-size: clamp(26px, 2.4vw, 36px); }
}
@media (min-width: 1441px) {
  .rw-sec.dc-hero .dc-proof__k { font-size: min(42px, calc(34.6px + var(--wx) * 0.0066)); }
  /* Above 1440 the paragraph's own cap (37rem, layout.css) stopped it 278px
     short of its column at 2560, a 386px empty band before the photo. The
     copy column is now the paragraph's measure, 35em of the growing type
     (595px at 1441, 682px at 2560, about 70 characters a line), and the
     photo takes the rest. */
  .rw-sec.dc-hero .row--split { grid-template-columns: minmax(0, 35em) minmax(0, 1fr); }
  .rw-sec.dc-hero .dc-hero__sub { max-width: 35em; }
}
/* The proof tiles' small uppercase labels were --g-fg-faint (#7C949B) on the
   light glass: 3.04-3.11:1 at 390, 1280 and 1920, in the old build too. In the
   site's secondary text colour, as the hero's paragraph is. */
.rw-sec.dc-hero .dc-proof__l { color: var(--g-fg-soft); }
/* /services/adult-eye-exams/ follows its first paragraph with a plain <p>,
   which had no margin, so the two read as one block (in the old build too).
   It gets the gap the two-paragraph pages have. */
.rw-sec.dc-hero .dc-hero__sub + p { margin-top: var(--ds-space-md); }

/* --- the visit page's hero --- */
@media (min-width: 1025px) {
  .rw-sec.ct-hero > .container {
    display: grid;
    grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr);
    column-gap: clamp(48px, 5vw, 96px);
    align-items: center;
  }
  .rw-sec.ct-hero > .container > .row:first-child { grid-column: 1; grid-row: 1; }
  .rw-sec.ct-hero .ct-hero__row { grid-template-columns: 1fr; }
  .rw-sec.ct-hero > .container > .row.ethc-stats { grid-column: 2; grid-row: 1; grid-template-columns: 1fr; gap: clamp(12px, 1.1vw, 18px); margin-top: 0; }
  .rw-sec.ct-hero .ethc-stat {
    flex-direction: row; align-items: center; gap: clamp(16px, 1.6vw, 26px);
    padding: clamp(14px, 1.3vw, 22px) clamp(18px, 1.6vw, 26px);
    background: var(--glass-bg); border: 1px solid var(--glass-brd); border-radius: var(--r-md); box-shadow: var(--glass-edge);
    -webkit-backdrop-filter: var(--glass-blur); backdrop-filter: var(--glass-blur);
  }
  .rw-sec.ct-hero .ethc-stat__k { flex: 0 0 2.1em; text-align: center; }
  .rw-sec.ct-hero .ethc-stat__l { max-width: none; }
}
/* Above 1440 the copy column is the copy's own measure (36em of the growing
   type), so the tiles start one gap after it: in a 1.5fr column the heading
   (10.4em) and paragraph (40rem) left a 336-440px band before them at
   2240-2560. */
@media (min-width: 1441px) {
  .rw-sec.ct-hero > .container { grid-template-columns: minmax(0, 36em) minmax(0, 1fr); }
}

/* --- the legal and statement pages' opening band (/privacy-policy/,
   /terms/, /disclaimer/, /accessibility/) --- From 1025px the eyebrow and
   heading stand on the left and the lede (and effective date) on the right;
   before, all of it sat in the left half, with 0-25% of the right half used
   at 1920-2560. The heading pair is centred on the lede without a wrapper:
   the lede spans the pair's two rows, the rows share its extra height
   equally, and the eyebrow sits at the foot of the first row and the heading
   at the head of the second, so the pair meets at the middle. /search/ has
   the same markup with its search form after the heading, and keeps its own. */
@media (min-width: 1025px) {
  body:not(.pg-home):not(.pg-search) main > .rw-sec.et-band:first-child > .container > .row > .col--measure:has(> .et-h1) {
    max-width: none;
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.25fr);
    grid-template-rows: auto auto;
    column-gap: clamp(48px, 5.5vw, 108px);
  }
  body:not(.pg-home):not(.pg-search) main > .rw-sec.et-band:first-child .col--measure:has(> .et-h1) > * { grid-column: 2; }
  body:not(.pg-home):not(.pg-search) main > .rw-sec.et-band:first-child .col--measure:has(> .et-h1) > .et-eyebrow { grid-column: 1; grid-row: 1; align-self: end; margin-bottom: 0; }
  body:not(.pg-home):not(.pg-search) main > .rw-sec.et-band:first-child .col--measure:has(> .et-h1) > .et-h1 { grid-column: 1; grid-row: 2; align-self: start; }
  body:not(.pg-home):not(.pg-search) main > .rw-sec.et-band:first-child .col--measure:has(> .et-h1) > .et-lede { grid-row: 1 / 3; align-self: center; margin-top: 0; max-width: 36em; }
  body:not(.pg-home):not(.pg-search) main > .rw-sec.et-band:first-child .col--measure:has(> .et-h1) > .bw-legal__effective { margin-top: var(--ds-space-sm); }
}

/* --- the product pages' photo badge (.tib-hero__chip, six pages) ---
   Positioned absolutely at the photo's foot by layout.css, but the generated
   glass block in components.css sets position: relative at the same weight
   and loads later, so since the first build the badge sat in the flow at the
   top of its photo, 21px of it cut off by the frame (the same trap as the
   badges in §23). */
.rw-sec .tib-hero__chip { position: absolute; }

/* =========================================================================
   29 · THE EYEWEAR PAGES: FULL-WIDTH CLOSE-UPS, AND THE DESIGNER HOUSES
   =========================================================================
   Operator, 2026-10-12: "for hero images of inner pages under EYEWEAR, I
   want to revise all the heroes. I want hero images that are high
   resolution and close-up photos of designer brands. Use higgsfield to
   generate high quality photos and make sure the hero background images
   are full width ... And then after updating the hero images on these
   internal pages, focus on the designer frames page and make sure to add a
   lot of designer frames and designer eyewears across the page, I want big
   brands featured in there with corresponding kick ass photo".

   THE HEROES. tools/build.mjs (EW_HERO) adds .ew-hero and .surface-dark to
   the first section of /products/ and of the four pages in its menu, and
   gives each a generated 16:9 close-up; /eye-health/ and /reviews/ use the
   same .tib-hero component and are not touched. .surface-dark gives the
   text, the pills, the call link and the badge the site's dark variants.
   · From 1200px the photograph is the section's background. The media box
     leaves the grid (absolute: the container, row and columns are not
     positioned, so it sits on the section itself) and spans the full
     width; the copy takes the left column (it ends at 45-51% of the
     window, measured) and the right is left to the eyewear, which each
     photograph places at x 57-96%. Under the text, a scrim in the page's
     own dark, --ew-ink: the mean colour of its photograph's left 45%.
   · Below 1200px the photograph is a full-width band above the text: the
     <picture> serves a 16:10 crop around the eyewear there; the band is
     16:10 up to 767px and 2:1 from 768, and its foot fades into the
     section's dark. The section keeps the dark, so the hero reads as one
     piece on a phone too.
   · site.js gives .tib-hero__media img a parallax (an inline transform:
     scale 1.06 and a drift). A background must not drift or grow, so
     that inline transform is overridden: the one !important here. */
.rw-sec.ew-hero { --ew-ink: #071114; background: var(--ew-ink); border-block: 0; }
.rw-sec.ew-hero.rw-p-sunglasses { --ew-ink: #051213; }
.rw-sec.ew-hero.rw-p-kids-eyewear { --ew-ink: #022630; }
.rw-sec.ew-hero.rw-p-contact-lenses { --ew-ink: #010a0f; }
.rw-sec.ew-hero.rw-p-eyewear { --ew-ink: #070908; }
/* the dark surface's grid glow: the photograph is the texture here */
.rw-sec.ew-hero::after { display: none; }
.rw-sec.ew-hero :is(.tib-hero__media, .et-hero__media) {
  overflow: hidden;
  isolation: isolate;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  max-height: none;
  background: var(--ew-ink);
}
.rw-sec.ew-hero :is(.tib-hero__media, .et-hero__media) img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  max-width: none;
  object-fit: cover;
  transform: none !important;
  transition: none;
}
.rw-sec.ew-hero :is(.tib-hero__media, .et-hero__media)::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  border-radius: 0;
  box-shadow: none;
}
.rw-sec.ew-hero .tib-hero__chip { z-index: 2; }
/* the badge's first line kept the light chip's ink on the dark glass */
.rw-sec.ew-hero .tib-hero__chip b { color: var(--c-1); }

@media (min-width: 1200px) {
  .rw-sec.ew-hero {
    --hero-top: clamp(72px, 6vw, 120px);
    padding-bottom: clamp(72px, 6vw, 120px);
  }
  .rw-sec.ew-hero > .container,
  .rw-sec.ew-hero :is(.tib-hero__grid, .row--split-media),
  .rw-sec.ew-hero :is(.tib-hero__grid, .row--split-media) > .col { position: static; }
  .rw-sec.ew-hero :is(.tib-hero__grid, .row--split-media) {
    /* the copy's measure grows with the window: 520px at 1200-1227, 672px
       at 1920, 760px from 2320; it ends at 45-51% of the window */
    --ew-copy: clamp(520px, calc(22vw + 250px), 760px);
    display: grid;
    grid-template-columns: minmax(0, var(--ew-copy)) minmax(0, 1fr);
    align-items: center;
  }
  .rw-sec.ew-hero :is(.tib-hero__grid, .row--split-media) > .col:last-child {
    grid-column: 1;
    grid-row: 1;
    position: relative;
    z-index: 1;
  }
  .rw-sec.ew-hero :is(.tib-hero__grid, .row--split-media) > .col:first-child { grid-column: 2; grid-row: 1; }
  /* The photograph's box is the section's full width and 56.25vw tall (16:9
     of the window; with a classic scrollbar that is about 8px more than 16:9
     of the section, so cover trims about 7px off each side), capped at the
     section's height. Where the section is wider than 16:9 (at 1920
     and 2560 on these pages; 1.70-1.76 at 1600) that is cover, cropping top
     and bottom.
     Where it is taller (1.36-1.59 wide at 1200-1440, measured), cover
     would scale the photograph to the HEIGHT: in a first build at 1280 the
     frames' left temple ran under the ends of the paragraph's lines and
     their lower half sat below a 585px window. Kept at full width instead,
     the eyewear stays at x 57-96% of the window at every width, and the
     box's foot fades into the section's dark for the rest of the height
     (up to 193px, at 1200). (Not aspect-ratio with max-height: Chrome
     carries the height cap over to the width, and the box stopped 117px
     short of the right edge at 1920.) */
  .rw-sec.ew-hero :is(.tib-hero__media, .et-hero__media) {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: auto;
    z-index: 0;
    width: auto;
    height: min(100%, 56.25vw);
    aspect-ratio: auto;
    margin: 0;
  }
  .rw-sec.ew-hero :is(.tib-hero__media, .et-hero__media) img { object-position: 50% 45%; }
  .rw-sec.ew-hero :is(.tib-hero__media, .et-hero__media)::after {
    background:
      linear-gradient(90deg,
        color-mix(in srgb, var(--ew-ink) 90%, transparent) 0%,
        color-mix(in srgb, var(--ew-ink) 78%, transparent) 34%,
        color-mix(in srgb, var(--ew-ink) 34%, transparent) 50%,
        transparent 60%),
      linear-gradient(180deg,
        color-mix(in srgb, var(--ew-ink) 36%, transparent) 0%,
        transparent 22%,
        transparent 72%,
        var(--ew-ink) 100%);
  }
  /* the badge: at the foot of the photograph's box, on the content's right
     edge. Where the box is the section (1920 and up) that is the section's
     foot; at 1200-1440 the box stops short, and the badge sits 123-224px
     above the section's foot, on the photograph's faded table (measured) */
  .rw-sec.ew-hero .tib-hero__chip {
    top: auto;
    left: auto;
    bottom: clamp(24px, 2.6vw, 44px);
    right: calc((100% - min(100%, var(--wrap))) / 2 + var(--gutter));
  }
}
@media (max-width: 1199px) {
  .rw-sec.ew-hero {
    --hero-top: 0px;
    padding-bottom: clamp(44px, 7vw, 72px);
  }
  .rw-sec.ew-hero :is(.tib-hero__grid, .row--split-media) {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    row-gap: clamp(26px, 4.4vw, 40px);
  }
  .rw-sec.ew-hero :is(.tib-hero__media, .et-hero__media) {
    position: relative;
    inset: auto;
    width: auto;
    max-width: none;
    margin-inline: calc(50% - 50vw);
    aspect-ratio: 16 / 10;
  }
  .rw-sec.ew-hero :is(.tib-hero__media, .et-hero__media) img { object-position: 50% 50%; }
  .rw-sec.ew-hero :is(.tib-hero__media, .et-hero__media)::after {
    background: linear-gradient(180deg,
      transparent 56%,
      color-mix(in srgb, var(--ew-ink) 64%, transparent) 84%,
      var(--ew-ink) 100%);
  }
}
@media (min-width: 768px) and (max-width: 1199px) {
  .rw-sec.ew-hero :is(.tib-hero__media, .et-hero__media) { aspect-ratio: 2 / 1; }
}
@media (max-width: 1199px) {
  /* The hub's copy box steps aside here (layout.css: display: contents
     below 1025px) and its eyebrow is ordered before the photograph, which
     left the eyebrow alone above the band. The photograph leads. */
  .rw-sec.ew-hero .et-hero__copy > .et-eyebrow { order: 0; }
  /* The badge sat inside the band's lower left and hid part of the eyewear
     (about 28% of the band on a 390px phone). It now straddles the band's
     foot, half on the fade and half on the section, on the text's left
     edge, and the text below starts clear of it. (In a desktop window with
     a classic scrollbar it sits 7.5px left of that edge: the band's 100vw
     includes the scrollbar. 0px on phones.) */
  .rw-sec.ew-hero .tib-hero__media { overflow: visible; }
  .rw-sec.ew-hero .tib-hero__chip {
    top: auto;
    right: auto;
    bottom: 0;
    left: calc((100vw - min(100vw, var(--wrap))) / 2 + var(--gutter));
    translate: 0 50%;
  }
  .rw-sec.ew-hero .tib-hero__grid { row-gap: clamp(60px, 9vw, 76px); }
}

/* THE DESIGNER HOUSES (/products/designer-frames/, after the hero): the
   eight houses the source names, each a card with a generated photograph
   in its house's design language, the house's own wordmark in white and a
   line on its design language (tools/build.mjs, EW_HOUSES). Four across
   from 821px, two below. The wordmarks are black on transparent in the
   source; brightness(0) invert(1) makes them white, and a soft shadow keeps
   the thin ones (the Maui Jim script) clear of a busy photograph. Each
   carries --h, its height relative to a 2:1 mark (tools/build.mjs), and
   they stand on a common baseline so the notes line up across a row. */
.rw-sec.ew-houses .ew-houses__grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(12px, 1.4vw, 24px);
  margin-top: clamp(28px, 3.4vw, 52px);
}
@media (min-width: 821px) {
  .rw-sec.ew-houses .ew-houses__grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
.rw-sec .ew-house {
  --ew-logo: clamp(28px, 2.6vw, 46px);
  position: relative;
  isolation: isolate;
  overflow: hidden;
  margin: 0;
  aspect-ratio: 3 / 4;
  border-radius: var(--r-lg);
  background: var(--c-3);
  box-shadow: var(--glass-shadow);
}
.rw-sec .ew-house__media { position: absolute; inset: 0; z-index: -1; }
.rw-sec .ew-house__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform var(--t-slow) var(--ease);
}
.rw-sec .ew-house:hover .ew-house__media img { transform: scale(1.045); }
.rw-sec .ew-house::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background: linear-gradient(180deg,
    transparent 40%,
    color-mix(in srgb, var(--c-3) 62%, transparent) 68%,
    color-mix(in srgb, var(--c-3) 92%, transparent) 100%);
}
.rw-sec .ew-house__body {
  position: absolute;
  inset: auto 0 0 0;
  display: grid;
  gap: clamp(6px, .7vw, 10px);
  padding: clamp(14px, 1.5vw, 24px);
}
.rw-sec .ew-house__name {
  display: flex;
  align-items: flex-end;
  min-height: calc(var(--ew-logo) * 1.1);
  margin: 0;
  line-height: 1;
}
.rw-sec .ew-house__logo {
  display: block;
  width: auto;
  height: calc(var(--h, 1) * var(--ew-logo));
  max-width: 100%;
  object-fit: contain;
  object-position: left bottom;
  filter: brightness(0) invert(1) drop-shadow(0 1px 5px rgb(0 0 0 / .5));
}
.rw-sec .ew-house__type {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(14px, 1.2vw, 20px);
  letter-spacing: .14em;
  line-height: 1.15;
  text-transform: uppercase;
  color: var(--c-1);
}
.rw-sec .ew-house__note {
  margin: 0;
  font-size: clamp(13.5px, 1vw, 16px);
  line-height: 1.4;
  color: color-mix(in srgb, var(--c-7) 90%, transparent);
}
.rw-sec.ew-houses .ew-houses__fine {
  margin: clamp(18px, 2vw, 28px) 0 0;
  font-size: 13.5px;
  color: var(--g-fg-soft);
}

/* THE THREE LOOKS ("Most people arrive with a look in mind"): each gets a
   photograph (tools/build.mjs, EW_LOOKS). Below 821px the photograph sits
   above its text; from 821px the two share a row, the middle look with its
   photograph on the left, and the heading row becomes a stack with a
   display-size title. */
.rw-sec .tib-collection--photo { display: grid; gap: clamp(16px, 2.4vw, 26px); }
.rw-sec .tib-collection--photo .tib-collection__media {
  order: -1;
  overflow: hidden;
  aspect-ratio: 4 / 3;
  border-radius: var(--r-lg);
  box-shadow: var(--glass-shadow);
}
.rw-sec .tib-collection--photo .tib-collection__media img { width: 100%; height: 100%; object-fit: cover; }
@media (min-width: 821px) {
  .rw-sec .tib-collection--photo {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.12fr);
    column-gap: clamp(32px, 4.6vw, 88px);
    align-items: center;
  }
  .rw-sec .tib-collection--photo .tib-collection__head {
    grid-column: 1;
    grid-row: 1;
    flex-direction: column;
    align-items: flex-start;
    gap: clamp(10px, 1vw, 16px);
    padding-bottom: 0;
    border-bottom: 0;
  }
  .rw-sec .tib-collection--photo .tib-collection__media { order: 0; grid-column: 2; grid-row: 1; }
  .rw-sec .tib-collection--photo-left { grid-template-columns: minmax(0, 1.12fr) minmax(0, 1fr); }
  .rw-sec .tib-collection--photo-left .tib-collection__head { grid-column: 2; }
  .rw-sec .tib-collection--photo-left .tib-collection__media { grid-column: 1; }
  .rw-sec .tib-collection--photo .tib-collection__title {
    font-family: var(--font-display);
    font-size: clamp(26px, 2.5vw, 42px);
    font-weight: 600;
    line-height: 1.08;
    letter-spacing: -.01em;
  }
  .rw-sec .tib-collection--photo .tib-collection__note { max-width: 30em; }
}

/* =========================================================================
   30 · THE ABOUT PAGE HERO: HIS PHOTOGRAPH, FULL WIDTH
   =========================================================================
   Operator, 2026-10-12: "update the about us page hero, I want the
   improved version of Dr. Hyder's photo utilized and made full width".
   /our-doctor/ only (.od-hero--wide, added by tools/build.mjs with the
   <picture>; the section's own classes are unchanged).

   The hero showed his edited portrait framed beside the copy. Now:
   · From 1025px the <picture> serves the 16:9 version of the same edited
     photograph (the doctor sections' file: him in the left third, the
     optical beyond him) as the section's full-width background. The copy
     moves to the right column, as in the doctor sections (§24): the photo
     has him on the left, and a real person's photograph is not mirrored.
     cover is anchored at 27% so he stays in the left column; a gradient
     in --c-3 darkens the right side behind the copy, whose colours turn
     light here only.
   · Below 1025px the section keeps its light band and its order (eyebrow,
     heading, photograph, paragraph ...), and the portrait becomes a
     full-width band: no frame, edge to edge, 4:3 on phones and 2:1 from
     768px, his face in the upper third. */
.rw-sec.od-hero--wide { overflow: hidden; }
.rw-sec.od-hero--wide .bw-founder__portrait {
  border: 0;
  border-radius: 0;
  box-shadow: none;
  max-height: none;
}
.rw-sec.od-hero--wide .bw-founder__portrait img { transform: none; transition: none; }
.rw-sec.od-hero--wide .bw-founder__portrait::after,
.rw-sec.od-hero--wide .bw-founder__portrait:hover::after {
  border-radius: 0;
  box-shadow: none;
}

@media (min-width: 1025px) {
  .rw-sec.od-hero--wide {
    --hero-top: clamp(64px, 6vw, 112px);
    padding-bottom: clamp(64px, 6vw, 112px);
    background: var(--c-3);
  }
  .rw-sec.od-hero--wide .bw-founder {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
    min-height: clamp(560px, 44vw, 760px);
    align-items: center;
  }
  .rw-sec.od-hero--wide .bw-founder__copy {
    grid-column: 2;
    grid-row: 1;
    position: relative;
    z-index: 1;
  }
  .rw-sec.od-hero--wide .bw-founder__portrait {
    position: absolute;
    inset: 0;
    z-index: 0;
    width: auto;
    height: auto;
    aspect-ratio: auto;
    margin: 0;
  }
  .rw-sec.od-hero--wide .bw-founder__portrait img { object-position: 27% 22%; }
  /* Measured at 1025-2560: his face sits at x 19-34% of the section, his
     elbow reaches 39-48%, and the copy starts at 50.6-51.6%. The gradient
     is clear to 36% and 86% dark by 49%: with the 56% stop of a first draft
     the copy's start sat on 71%, and the gold eyebrow there measured 4.19:1
     at 2560 against the bright frame wall. */
  .rw-sec.od-hero--wide .bw-founder__portrait::after,
  .rw-sec.od-hero--wide .bw-founder__portrait:hover::after {
    background:
      linear-gradient(90deg,
        color-mix(in srgb, var(--c-3) 0%, transparent) 0%,
        color-mix(in srgb, var(--c-3) 0%, transparent) 36%,
        color-mix(in srgb, var(--c-3) 50%, transparent) 42%,
        color-mix(in srgb, var(--c-3) 86%, transparent) 49%,
        color-mix(in srgb, var(--c-3) 90%, transparent) 100%),
      linear-gradient(180deg,
        color-mix(in srgb, var(--c-3) 30%, transparent) 0%,
        transparent 18%,
        transparent 82%,
        color-mix(in srgb, var(--c-3) 40%, transparent) 100%);
  }
  /* the copy on the dark side */
  .rw-sec.od-hero--wide .bw-founder__kicker { color: var(--c-9); }
  .rw-sec.od-hero--wide .bw-founder__h { color: var(--c-1); }
  .rw-sec.od-hero--wide .bw-founder__h .ac { color: var(--c-9); }
  .rw-sec.od-hero--wide .bw-founder__lede { color: var(--g-on-dark-soft); }
  .rw-sec.od-hero--wide .od-hero__quote { color: var(--c-7); }
  .rw-sec.od-hero--wide .bw-founder__sig-name { color: var(--c-1); }
  .rw-sec.od-hero--wide .bw-founder__sig-role { color: var(--g-on-dark-soft); }
  .rw-sec.od-hero--wide .btn-ghost {
    color: var(--c-1);
    background: color-mix(in srgb, var(--c-1) 8%, transparent);
    border-color: color-mix(in srgb, var(--c-1) 24%, transparent);
  }
  .rw-sec.od-hero--wide .btn-ghost:hover {
    color: var(--c-1);
    background: color-mix(in srgb, var(--c-1) 16%, transparent);
    border-color: color-mix(in srgb, var(--c-1) 40%, transparent);
  }
}
@media (max-width: 1024px) {
  .rw-sec.od-hero--wide .bw-founder__portrait {
    width: auto;
    max-width: none;
    margin-inline: calc(50% - 50vw);
    aspect-ratio: 4 / 3;
  }
  .rw-sec.od-hero--wide .bw-founder__portrait img { object-position: 50% 18%; }
}
@media (min-width: 768px) and (max-width: 1024px) {
  .rw-sec.od-hero--wide .bw-founder__portrait { aspect-ratio: 2 / 1; }
}

/* =========================================================================
   31 · THE ABOUT PAGE TIMELINE: ROOM INSIDE AND BETWEEN THE CARDS
   =========================================================================
   Operator, 2026-10-12, on "How this practice started" (/our-doctor/,
   .bw-timeline, the only page with it): "the text in the box are too
   squeezed in, fix the spacing and padding".

   The source's timeline was a list: layout.css keeps its geometry, rows
   with vertical padding only and a 44px left gutter for a rail and dots,
   whose visuals were stripped and are not drawn. components.css then made
   each row a glass card (background, border, radius, shadow) but kept the
   row's zero side padding, and its list-row hover set the left padding to
   8px. So the text sat on the cards' left edge (on phones on both edges),
   the cards touched, and the empty gutter took 44px. Measured before: side
   padding 0, gap 0, 8-9px between title and paragraph at every width.
   · The gutter goes (nothing is drawn in it): the cards line up with the
     section heading.
   · The cards stand apart (12-20px) and get padding on every side
     (20-32px top and bottom, 20-40px at the sides); hover keeps it, so the
     text no longer jumps to 8px.
   · A little more room under each title. */
.rw-sec .bw-timeline__track {
  display: grid;
  gap: clamp(12px, 1.4vw, 20px);
  padding-left: 0;
}
.rw-sec .bw-timeline__entry,
.rw-sec .bw-timeline__entry:hover {
  --tl-pad-x: clamp(20px, 2.6vw, 40px);
  padding: clamp(20px, 2.4vw, 32px) var(--tl-pad-x);
}
.rw-sec .bw-timeline__h { margin-bottom: clamp(10px, .9vw, 14px); }

/* =========================================================================
   32 · THE ABOUT PAGE BIO: THE DOCTOR SECTIONS' DESIGN
   =========================================================================
   Operator, 2026-10-12, on "Who I am, in plain terms" (/our-doctor/,
   .od-biosec): "make this section the same format and design as the
   enhanced Dr. Hyder full width sections we did before" - the doctor
   sections (§24) and the About hero (§30). tools/build.mjs (reshapeAboutBio)
   wraps the edited portrait in a <picture> whose source serves the 16:9
   version from 1025px, and gives the section the doctor sections' dark
   surface: .surface-dark in place of the light .et-band--warm and its
   .et-band--seam haze, plus .od-biosec--wide for these rules.

   The section was a light band: the heading block, then a glass card with
   his framed portrait on the left and his name, role, two paragraphs and
   two contact links on the right. Now:
   · The card goes at every width. .bw-team__member is display:contents, and
     its glass highlight (components.css, an absolute ::after) is removed:
     with the card's box gone it would spread over the whole section.
   · Phones and tablets (the base rules - mobile-first, so no zoomed width
     between 1024 and 1025px falls through both, see §26): the heading, then
     the portrait as a full-width band - no frame, edge to edge, 4:3 on
     phones and 2:1 from 768px, his face in the upper third - then his name
     and the text.
   · 1025px and up: the 16:9 photograph covers the whole section with him on
     the left (27%), and every line of text is in the right column over a
     gradient in --c-3 - the columns, gap and gradient of the About hero
     (§30). The section is at least 560-760px tall (44vw), the text centred
     in it. A real person's photograph is not mirrored, so the text is
     always on the right.
   · The two contact links lose the empty 6px .dot before each (its visuals
     were stripped and it is not drawn, as with the timeline's gutter in
     §31), so they line up with the text above instead of 14px in.
   · Below 1025px the text now has the container's full width, and the two
     paragraphs ran 929px at 1024 (about 115 characters a line; the card's
     column had held them to 560px). They take the site's running-text
     measure, 35em (§27), which they already had from 1441px; at 1025-1440
     the right column is narrower than that, so nothing changes there. */
.rw-sec.od-biosec--wide { overflow: hidden; }
.rw-sec.od-biosec--wide .bw-team { max-width: none; }
.rw-sec.od-biosec--wide .bw-team__member { display: contents; }
.rw-sec.od-biosec--wide .bw-team__member::after { content: none; }
.rw-sec.od-biosec--wide .bw-team__portrait {
  width: auto;
  max-width: none;
  max-height: none;
  margin-inline: calc(50% - 50vw);
  aspect-ratio: 4 / 3;
  border-radius: 0;
}
.rw-sec.od-biosec--wide .bw-team__portrait img { object-position: 50% 18%; }
.rw-sec.od-biosec--wide .bw-team__bio { max-width: 35em; }
.rw-sec.od-biosec--wide .bw-team__contact .dot { display: none; }
.rw-sec.od-biosec--wide .bw-team__contact a { color: var(--c-1); }
.rw-sec.od-biosec--wide .bw-team__contact a:hover { color: var(--c-9); }
@media (min-width: 768px) {
  .rw-sec.od-biosec--wide .bw-team__portrait { aspect-ratio: 2 / 1; }
}
@media (min-width: 1025px) {
  .rw-sec.od-biosec--wide .col {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
    column-gap: clamp(32px, 5vw, 72px);
    align-content: center;
    min-height: clamp(560px, 44vw, 760px);
  }
  .rw-sec.od-biosec--wide .bw-team { display: contents; }
  .rw-sec.od-biosec--wide .et-sec-head,
  .rw-sec.od-biosec--wide .bw-team__body {
    grid-column: 2;
    position: relative;
    z-index: 1;
  }
  .rw-sec.od-biosec--wide .bw-team__portrait {
    position: absolute;
    inset: 0;
    z-index: 0;
    margin: 0;
    aspect-ratio: auto;
  }
  .rw-sec.od-biosec--wide .bw-team__portrait img { object-position: 27% 22%; }
  .rw-sec.od-biosec--wide .bw-team__portrait::after {
    content: "";
    position: absolute;
    inset: 0;
    pointer-events: none;
    background:
      linear-gradient(90deg,
        color-mix(in srgb, var(--c-3) 0%, transparent) 0%,
        color-mix(in srgb, var(--c-3) 0%, transparent) 36%,
        color-mix(in srgb, var(--c-3) 50%, transparent) 42%,
        color-mix(in srgb, var(--c-3) 86%, transparent) 49%,
        color-mix(in srgb, var(--c-3) 90%, transparent) 100%),
      linear-gradient(180deg,
        color-mix(in srgb, var(--c-3) 30%, transparent) 0%,
        transparent 18%,
        transparent 82%,
        color-mix(in srgb, var(--c-3) 40%, transparent) 100%);
  }
}

/* =========================================================================
   33 · PHONES: ALIGNMENT, SPACING AND PADDING, AND THE DECORATIONS THAT
        WERE NEVER DRAWN
   =========================================================================
   Operator, 2026-10-16: "I need you to optimize the mobile. There are a lot
   of alignment, spacing and padding issues in mobile".

   All 43 pages were captured at 390px and measured at 360, 390 and 414:
   text off the gutter, cramped or lopsided card padding, one card mixing
   centred and left-aligned text, ragged stacks, blocks touching. Two kinds
   of fault came out of it.

   A. AT EVERY WIDTH: decorations that were never drawn. layout.css keeps
      the source's geometry and strips its visuals, and a few properties went
      with them that are not visual at all (list-style:none, the content of a
      ::before bullet, SVG fills), plus small backgrounds no other file
      replaced. Every source rule was compared with the built pages to find
      them. What they did:
      · custom-bullet lists showed the browser's disc 28px left of the text,
        on a phone 3-8px from the screen edge, and no bullet of their own;
      · the map's pin and both its rings were one solid black disc, its
        roads thin black lines;
      · empty dot boxes pushed chip labels off centre, and the .et-dot inside
        a pill took the pill's own skin: an empty white oval;
      · icon boxes with no tile left the glyph 10-17px in from the text it
        heads; review initials had no circle; the About quote was indented
        for a gold bar that was not there;
      · long reviews had no "See more", so nothing said they open;
      · bold text in a dark band stayed dark ink (the practice name in
        "Read enough?" was a ghost).
      Four faults come from rules meeting: components.css gives glass to two
      things that are not cards (each FAQ answer, inside its FAQ card, its
      text on the glass's left edge; the legal pages' "On this page" label);
      on the one dark band that is also a seam (cataract) the seam's white
      haze took the dark edge's 92px width, a grey-white block in the corner;
      and §4 made eyebrows inline-flex, so the eyebrow after the second
      section's inline icon sat 57-81px right of its heading.
      They are drawn as the source drew them, in this site's colours. The
      eyebrow bars stay out (removed on request, §4).
      Some card text was left as body text too. Only the cards fixed here get
      their hierarchy back: the related-care cards, the service pages' stat
      band, the eyewear and guide cards (.et-frame), the hero photo's caption
      chip. Other text roles across the site are left as they are.

   B. PHONES: layout. Below 641px unless a rule says otherwise. */

/* --- A1 · lists with their own bullets ----------------------------------- */
.rw-sec :is(.dc-steps, .dc-steplist, .dc-cap__steps, .dc-cap__ul, .dc-worries, .od-facts, .ia-bring, .bw-toc__list) {
  list-style: none;
}
.rw-sec :is(.dc-steps, .dc-steplist, .dc-cap__steps, .dc-cap__ul, .dc-worries, .od-facts, .ia-bring) > li::before {
  content: "";
  position: absolute;
  left: 0;
  border-radius: 50%;
  background: var(--g-teal);
}
/* centred on the first line: half a line-height down, less half the dot */
.rw-sec :is(.dc-steps, .dc-steplist, .dc-cap__steps, .dc-cap__ul, .dc-worries) > li::before {
  top: .56em;
  top: calc(.5lh - 4.5px);
  width: 9px;
  height: 9px;
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--g-teal) 15%, transparent);
}
.rw-sec .od-facts > li::before {
  top: .47em;
  top: calc(.5lh - 6px);
  width: 12px;
  height: 12px;
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--g-teal) 16%, transparent);
}
.rw-sec .ia-bring > li::before {
  top: .62em;
  top: calc(.5lh - 3.5px);
  width: 7px;
  height: 7px;
}
.surface-dark :is(.dc-steps, .dc-steplist, .dc-cap__steps, .dc-cap__ul, .dc-worries, .od-facts, .ia-bring) > li::before {
  background: var(--g-gold-lit);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--g-gold-lit) 18%, transparent);
}

/* --- A2 · the legal pages' "On this page" is a label, not a card -------- */
.rw-sec .bw-toc .bw-toc__title,
.rw-sec .bw-toc .bw-toc__title:hover {
  background: none;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  transform: none;
}
.rw-sec .bw-toc .bw-toc__title::after { content: none; }

/* --- A3 · the map in the visit card ------------------------------------- */
.rw-sec .ct-find__art { color: var(--g-teal); }
.rw-sec .ct-find__roads { stroke-width: 12; opacity: .15; }
.rw-sec .ct-find__road-main { stroke-width: 5; opacity: .32; }
.rw-sec .ct-find__ping { fill: var(--g-teal); opacity: .12; }
.rw-sec .ct-find__ping--out { opacity: .06; }
.rw-sec .ct-find__pin { fill: var(--g-teal); }
.rw-sec .ct-find__dot { fill: var(--c-1); }

/* --- A4 · dots ---------------------------------------------------------- */
.rw-sec .et-pill > .et-dot,
.rw-sec .et-pill > .et-dot:hover {
  flex: none;
  width: 7px;
  height: 7px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: var(--g-teal);
  box-shadow: none;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  transform: none;
}
.surface-dark .et-pill > .et-dot { background: var(--g-gold-lit); }
.rw-sec .tib-chip .tib-chip__dot { border-radius: 50%; background: var(--g-gold); }
.rw-sec .ethc-house .ethc-house__mk { border-radius: 50%; background: linear-gradient(135deg, var(--g-teal-lit), var(--g-gold)); }
.rw-sec .ethc-plan .ethc-plan__mk { border-radius: 50%; background: var(--g-teal); }
.rw-sec .ethc-plan--pay .ethc-plan__mk { background: var(--g-gold); }
.rw-sec .ethc-close__note .dot { border-radius: 50%; background: var(--g-teal); }

/* --- A5 · review initials ----------------------------------------------- */
.rw-sec .et-avatar {
  border-radius: 50%;
  font-family: var(--font-display);
  font-size: 14.5px;
  font-weight: 700;
  letter-spacing: .02em;
  color: var(--c-1);
  background: linear-gradient(135deg, var(--g-teal), var(--g-teal-deep));
  box-shadow: inset 0 1px 0 color-mix(in srgb, var(--c-1) 24%, transparent);
}

/* --- A6 · icon tiles: the §11 tile, at each box's own size -------------- */
.rw-sec :is(.ia-panel__ic, .ia-link__ic, .ia-heads__ic, .dc-chip__ic, .tib-hero__ring, .ethc-why__arrow) {
  border-radius: 14px;
  color: var(--g-teal);
  background: linear-gradient(150deg, color-mix(in srgb, var(--g-teal-lit) 16%, transparent), color-mix(in srgb, var(--g-gold) 14%, transparent));
  border: 1px solid color-mix(in srgb, var(--c-1) 70%, transparent);
  box-shadow: inset 0 1px 0 color-mix(in srgb, var(--c-1) 90%, transparent);
}
.rw-sec :is(.dc-chip__ic, .tib-hero__ring) { border-radius: 11px; }
.rw-sec .ethc-why__arrow { border-radius: 50%; }   /* turned 90deg on phones */
.surface-dark :is(.ia-panel__ic, .ia-link__ic, .ia-heads__ic, .ethc-why__arrow) {
  color: var(--g-gold-lit);
  background: color-mix(in srgb, var(--c-1) 9%, transparent);
  border-color: color-mix(in srgb, var(--c-1) 16%, transparent);
  box-shadow: inset 0 1px 0 color-mix(in srgb, var(--c-1) 14%, transparent);
}

/* --- A7 · "Leave a review" is a <button>: it had the browser's own skin -- */
.rw-sec button.et-golink {
  -webkit-appearance: none;
  appearance: none;
  margin: 0;
  padding: 0;
  background: none;
  border: 0;
  border-radius: 0;
  font-family: inherit;
  line-height: inherit;
  cursor: pointer;
}

/* --- A8 · reviews: long ones say they open; one colour for every quote ---
   A short review's quote is a <p>, so ".site-content p" (0,1,1) turned it
   grey; a long one's is a <span> in <summary> and kept the quote colour. */
.et-review__more > summary { list-style: none; cursor: pointer; }
.et-review__more > summary::-webkit-details-marker { display: none; }
.et-review__more > summary::after {
  content: "See more";
  display: block;
  margin-top: var(--ds-space-xs);
  font-family: var(--font-display);
  font-size: var(--fs-19);
  font-weight: 620;
  letter-spacing: 0;
  color: var(--g-teal);
}
.et-review__more > summary:hover::after { color: var(--g-teal-deep); }
.et-review__more[open] > summary::after { content: none; }
.surface-dark .et-review__more > summary::after { color: var(--g-gold-lit); }
.site-content .et-review p.et-review__q { color: var(--g-fg); }

/* --- A9 · bold text in a dark band: most already had the on-dark colour
   from its paragraph; one in a NAP block kept §3's dark ink ------------- */
.site-content .surface-dark :is(b, strong) { color: var(--g-on-dark); }

/* --- A10 · an FAQ answer is text inside its card, not a second card ----- */
.rw-sec .dc-faq__item > .dc-faq__a {
  background: none;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}

/* --- A11 · no white seam haze on a dark band ---------------------------- */
.rw-sec.surface-dark.et-band--seam::before { content: none; }

/* --- A12 · two pages build the visit card's rows as a <ul> -------------- */
.rw-sec ul.dc-visit__list {
  margin-bottom: 0;
  padding-left: 0;
  list-style: none;
}

/* --- A13 · the second section's icon is a block: its eyebrow and heading
   share one left edge ------------------------------------------------------ */
.rw-sec .dc-sq__aside > svg { display: block; }

/* --- A14 · the About quote's gold bar ----------------------------------- */
.rw-sec .od-hero__quote { border-left: 3px solid var(--g-gold); }

/* --- A15 · a list followed by a paragraph: the lists' margin-bottom is 0 -- */
.rw-sec .dc-prose > :is(ul, ol) + p { margin-top: var(--ds-space-md); }

/* --- A16 · the parent-hub card sat on the related cards with no gap ----- */
.rw-sec .dc-relrow { margin-top: var(--et-gap); }

/* --- A17 · card hierarchy ------------------------------------------------ */
.rw-sec .dc-relhub__ey,
.rw-sec .et-frame__brand {
  font-family: 'Space Mono', ui-monospace, monospace;
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--g-teal);
}
.rw-sec .dc-relhub__t {
  font-family: var(--font-display);
  font-size: clamp(21px, 2.2vw, 28px);
  font-weight: 700;
  line-height: 1.15;
  letter-spacing: -.025em;
  color: var(--g-fg);
}
.rw-sec :is(.dc-rel__t, .et-frame__name, .ha-cond__t):not(h2, h3, h4) {   /* the eyewear hub's are h3s, styled as headings */
  font-family: var(--font-display);
  font-size: 18.5px;
  font-weight: 650;
  line-height: 1.25;
  letter-spacing: -.018em;
  color: var(--g-fg);
}
.rw-sec :is(.dc-relhub__go, .et-frame__add) {
  font-size: var(--fs-19);
  font-weight: 620;
  color: var(--g-teal);
}
.rw-sec .et-frame__add { gap: var(--sp-19); padding-inline: 0; }
.rw-sec .dc-relhub:hover .dc-relhub__go,
.rw-sec .et-frame__add:hover { color: var(--g-teal-deep); }
.surface-dark :is(.dc-relhub__ey, .et-frame__brand, .dc-relhub__go, .et-frame__add) { color: var(--g-gold-lit); }
.surface-dark :is(.dc-relhub__t, .dc-rel__t, .et-frame__name, .ha-cond__t) { color: var(--c-1); }
/* a second link in the visit card (one page) */
.rw-sec .dc-visit__more { font-size: var(--fs-19); font-weight: 620; color: var(--g-teal); }
.rw-sec .dc-visit__more:hover { color: var(--g-teal-deep); }
/* the visit card's rows are not prose: on the two pages that build them as
   <li>, §3's "li > a" underline gave their links one that the <div> rows on
   the other 19 pages do not have */
.site-content .dc-visit .dc-visit__list li.dc-visit__row > a {
  box-shadow: none;
  background-image: none;
  text-decoration: none;
}
/* the dark "Read enough?" band's NAP: its links were plain white text */
.surface-dark .tib-creed__nap a { color: var(--g-gold-lit); font-weight: 620; }
.surface-dark .tib-creed__nap a:hover { color: var(--c-1); }
/* the About page's "Who I am" links, likewise: §32 made them white, gold on
   hover, and they read as more paragraph text; the doctor sections whose
   design that section takes give their links the gold */
.rw-sec.od-biosec--wide .bw-team__contact a { color: var(--g-gold-lit); font-weight: 620; }
.rw-sec.od-biosec--wide .bw-team__contact a:hover { color: var(--c-1); }
/* a go-link's arrow keeps its size when the label wraps */
.rw-sec .et-golink > svg { flex: none; }
/* the home page's address line: the dot on its first line */
.rw-sec .ethc-close__note { align-items: flex-start; }
.rw-sec .ethc-close__note .dot { margin-top: .6em; margin-top: calc(.5lh - 3.5px); }
/* the numbers of the service pages' dark stat band and the doctor bands'
   stat tiles: numbers, not a line of body text. components.css gives the
   site's other stat numbers this treatment (§9); these two were not in its
   list */
.rw-sec :is(.dc-stat__k, .et-stat__k) {
  display: block;
  font-family: var(--font-display);
  font-size: clamp(30px, 3.6vw, 46px);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -.035em;
  font-variant-numeric: tabular-nums;
  background: linear-gradient(100deg, var(--g-gold-lit), var(--g-teal-lit));
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
}
.rw-sec .et-stat__k .et-suf { font-size: .5em; letter-spacing: 0; margin-left: .08em; }
/* the caption chips on the hero photos: a display line over a small one
   (the product heroes' chip is dark glass, so its colours are inherited) */
.rw-sec .tib-hero__chip b {
  display: block;
  font-family: var(--font-display);
  font-size: 17px;
  font-weight: 700;
  line-height: 1.15;
  letter-spacing: -.015em;
}
.rw-sec .tib-hero__chip b + span {
  display: block;
  margin-top: 2px;
  font-size: 12.5px;
  line-height: 1.35;
  opacity: .8;
}
.rw-sec .dc-chip__k {
  display: block;
  font-family: var(--font-display);
  font-size: 17px;
  font-weight: 700;
  line-height: 1.15;
  letter-spacing: -.015em;
  color: var(--g-fg);
}
.rw-sec .dc-chip__l {
  display: block;
  margin-top: 2px;
  font-size: 12.5px;
  line-height: 1.35;
  color: var(--g-fg-soft);
}

/* --- B · phones ---------------------------------------------------------- */

/* B1 · below 1025px a split row stacks and layout.css flattens its text
   column (display:contents on the column AND its children), so a wrapper's
   children can be ordered around the photo. Where the column has no
   wrapper, the flattened children are the eyebrow, heading and paragraphs
   themselves: their text ran together as one paragraph (seven pages:
   .ha-depth on five card services and /services/, and /products/). Their
   boxes come back, in the order the wrapped rows use: eyebrow and heading,
   photo, text. A go-link in a flattened column no longer stretches across
   it, so its underline is as long as its text. */
@media (max-width: 1024px) {
  .rw-sec .row--split-media > .col:last-child > :is(p, h2, h3, ul, ol) {
    display: block;
    margin-block: 0;
  }
  .rw-sec .row--split-media > .col:last-child > :is(.et-eyebrow, .et-h2, .et-h3) { order: -1; }
  .rw-sec .row--split-media > .col:last-child > :is(p, ul, ol):not(.et-eyebrow) { order: 1; }
  .rw-sec .row--split-media .et-golink { justify-self: start; }
  .rw-sec .et-lede + .bw-legal__effective { margin-top: var(--ds-space-sm); }
}

@media (max-width: 640px) {
  /* B2 (rhythm) and B3 (page heading sizes) gave way to §34, which takes
     the reference build's sizes (revision 27) */
  .rw-sec :is(.et-eyebrow, .ha-hero__eyebrow) { text-wrap: balance; }

  /* B4 · the dark photo hero runs edge to edge: no card corners at the
     screen's edges and no pale strips above and below it, the text on the
     page's gutter, the call link on the copy's edge (the eyebrow's distance
     to its heading is §34's) */
  .rw-sec.ha-hero { --hero-top: 0px; padding-bottom: 0; }
  .rw-sec.ha-hero .ha-hero__stage { border: 0; border-radius: 0; }
  .rw-sec.ha-hero .ha-hero__inner { padding-inline: var(--gutter); }
  .rw-sec :is(.ha-hero__call, .tib-herocall, .ethc-herocall, .et-hero__call) { padding-inline: 0; }

  /* B5 · the hero proof tiles are one width (the buttons' widths and the
     chip rows are §34's: the reference's) */
  .rw-sec.dc-hero .dc-proof {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 10px;
  }

  /* B7 · the second section of a service page: icon, eyebrow and heading
     on one edge, the heading near its text */
  .rw-sec .dc-sq__aside > svg { margin-bottom: 14px; }
  .rw-sec .row--split:has(> .col > .dc-sq__aside) { row-gap: 14px; }

  /* B8 · related care: cards left-aligned (chrome.css §12 no longer centres
     them), the hub's link on its text's edge (its padding is §34's) */
  .rw-sec .dc-relhub__go { padding-inline: 0; }

  /* B9 (FAQ answer padding) and B10 (prose list indent and item spacing)
     gave way to §34 */
  /* one page's step list carries the source's inline 40px indent */
  .rw-sec .dc-prose > ul.dc-steps[style*="padding-left"] { padding-left: 0 !important; }
  /* the patient-forms list sat 38px under the sentence that introduces it */
  .rw-sec .ia-panel__note + .ia-bring { margin-top: 0; }

  /* B11 · photos that touched the text above or each other */
  .rw-sec .dc-pillhead > .dc-frame { margin-top: var(--ds-space-md); }
  .rw-sec .dc-frame + .dc-frame { margin-top: 14px; }

  /* B12 · the dark stat band's labels use the column */
  .rw-sec .dc-stat__l { max-width: none; }

  /* B13 · doctor sections: the full-bleed portrait opens the band, the
     stats sit under the chips and fill the column */
  .rw-sec.et-doctor:has(.row--split .et-doctor__media) { padding-top: 0; }
  .rw-sec.et-doctor .et-doctor__stats { padding-top: 0; }
  .rw-sec.et-doctor .et-doctor__stats > .et-stat { flex: 1 1 100%; }
  .rw-sec.et-doctor .et-stat__l { max-width: none; }

  /* B14 · cards with an icon column: the icon above, the text full width */
  .rw-sec .ha-cond:has(> .ha-cond__ic) { flex-direction: column; }
  .rw-sec .ia-heads { flex-direction: column; gap: 12px; }
  .rw-sec .ia-panel__head { gap: 12px; }

  /* B15 · labels that ran into their sentence */
  .rw-sec .ia-callout__k { display: flex; margin: 0 0 8px; }

  /* B16 · reviews: footer on one edge; the quote's own margin goes (the
     long reviews have none) */
  .rw-sec .et-reviews__foot {
    flex-direction: column;
    align-items: flex-start;
    gap: 14px;
  }
  .rw-sec .et-review p.et-review__q:not(.et-review__rest) { margin-bottom: 0; }

  /* B17 · the guide library: a 264px band of empty icon per card */
  .rw-sec .et-frame__media:has(> svg) { aspect-ratio: auto; height: 150px; }
  .rw-sec .et-frame__media > svg { width: 80px; height: 80px; }
  /* the eyewear hub cards' foot: the link, then the note under it */
  .rw-sec .et-frame__foot { flex-direction: column; align-items: flex-start; gap: 4px; }

  /* B18 (the product heroes' heading margin) gave way to §34 */

  /* B19 · the category cards' arrow on the card's padding edge */
  .rw-sec .et-cat__arrow { width: 18px; height: 18px; }

  /* B20 · service cards: the link near its text (the card's gap is §34's) */
  .rw-sec .et-svc__foot { padding-top: 0; }

  /* B21 · About page */
  .rw-sec .od-close__links { flex-direction: column; align-items: flex-start; gap: 4px; }
  .rw-sec .bw-founder__sig {
    margin-top: 20px;
    padding-top: 0;
    flex-direction: column;
    align-items: flex-start;
    gap: 2px;
  }

  /* B22 · NAP blocks: the phone between the address rows is a row too (it
     sat 5px from the next one with no divider); in the dark bands the
     eyebrow sits close to the lead (with no heading between, its margin and
     the lead's added up to 42px) */
  .rw-sec .tib-creed__nap { gap: 8px; }
  .rw-sec .tib-creed__copy > .et-eyebrow + .tib-creed__q { margin-top: 0; }
  .rw-sec .ha-nap > .ha-nap__phone {
    margin: 0 0 18px;
    border-bottom: 1px solid color-mix(in srgb, var(--c-3) 9%, transparent);
  }

  /* B23 · legal pages: paragraphs of one section closer than the sections
     (the last keeps layout.css's 0, or it adds to the section's padding);
     their table of contents on the label's edge */
  .rw-sec .bw-legal p:not(:last-child) { margin-bottom: 20px; }
  .rw-sec .bw-legal h2 { margin-top: 48px; }
  .rw-sec .bw-toc .bw-toc__link { padding-inline: 0; }

  /* B24 · search: no empty results row before a search */
  .rw-sec .row:has(.search-results:empty) { display: none; }

  /* B27 · the one heading set between two rows of cards ("Getting here")
     touched the card above it */
  .rw-sec .container > .row + .et-h3 { margin: 40px 0 14px; }
}

/* B25 · numbered rows: the number and its icon side by side on the left,
   above their left-aligned text (layout.css stacks the row at 560px) */
@media (max-width: 560px) {
  .rw-sec .dc-pill__badge {
    flex-direction: row;
    align-items: center;
    justify-content: flex-start;
    gap: 12px;
  }
  /* the hero photo's caption chip: inside the frame on both sides */
  .rw-sec .dc-chip { max-width: calc(100% - 2 * clamp(12px, 4vw, 16px)); }
}

/* B26 · the comparison cards' arrow turns down below 769px: its tile on the
   text edge */
@media (max-width: 768px) {
  .rw-sec .ethc-why__arrow { justify-self: start; }
}

/* =========================================================================
   34 · PHONES: THE REFERENCE BUILD'S PADDING AND SIZING
   =========================================================================
   Operator, 2026-10-16: "I'm still not happy with how elements presents
   itself in mobile. Perhaps you can refer to this build
   https://mikko-creator.github.io/thehighway90-redesign/ and use the exact
   padding and sizing from that reference build and apply it to eye trends
   mobile."

   Up to 700px, the reference's own phone breakpoint. Each value was read
   from the reference's stylesheets (its 700px block and the base rules it
   keeps there), checked on its pages at 390px, and given to the element
   here that does the same job. What moves is size and space: type sizes,
   line heights, padding, margins, gaps, minimum heights, corner radii.
   Fonts, weights, letter-spacing, colours and the glass stay this site's.
   Values in the comments are at 390px. chrome.css §14 does the top bar,
   header, menu, footer, booking form and the links' tap areas.

   §33's phone rules for the same things went: its rhythm, heading sizes,
   full-width buttons, chip columns, prose list spacing, FAQ answer padding,
   card padding and gaps. The rest of §33 is layout this section keeps. */
@media (max-width: 700px) {

  /* C1 · page gutter 16px (clamp(16px, 4vw, 44px)); 60px above and below
     each section */
  :root { --gutter: clamp(16px, 4vw, 44px); --flow: 60px; }

  /* C2 · running text 16.14px (clamp(1rem, .96rem + .2vw, 1.0875rem)) on
     1.65 */
  body { font-size: clamp(1rem, .96rem + .2vw, 1.0875rem); }

  /* C3 · headings, on the reference's tight leading. The reference's
     formulas keep growing past phone widths into its own desktop sizes;
     this site's sizes from 701px are smaller (a 36px page heading, a 27px
     section heading), so each formula stops growing at its 430px value,
     the widest phone. From 360 to 430px every size is the reference's; up
     to 700px they hold, and the step down at 701px is small (the home
     heading 41.6 to 36, the section headings 33 to 27, the page headings
     half a pixel). */
  .rw-sec.ethc-hero .ethc-hero__h {
    font-size: 2.6rem;      /* 41.6: clamp(2.6rem, 1.4rem + 4.4vw, ...) is at its minimum to 436px */
    line-height: .96;
  }
  /* page headings run to 4-7 lines here (the reference's are short), and on
     .96 a parenthesis or descender met the next line's ascenders (1px of
     ink overlap on the pink-eye heading): 1 keeps them apart */
  .rw-sec :is(.ha-hero__h, .dc-hero__h, .ct-hero__h, .tib-hero__h, .et-hero__h, .bw-founder__h, .et-h1) {
    font-size: clamp(1.9rem, 1.1rem + 4.4vw, 2.2825rem);          /* 34.76 */
    line-height: 1;
  }
  .rw-sec .et-h2 {
    font-size: clamp(1.75rem, 1.2rem + 3.2vw, 2.06rem);           /* 31.68 */
    line-height: .98;
    margin: 0 0 .5em;
  }
  .rw-sec .bw-legal h2 {
    font-size: 1.7rem;      /* 27.2: clamp(1.7rem, 1.2rem + 1.6vw, ...) is at its minimum to 500px */
    line-height: .98;
    margin-bottom: .5em;
  }
  .rw-sec :is(.et-h3, .dc-pill__t) {
    font-size: clamp(1.25rem, 1.05rem + .8vw, 1.265rem);          /* 20 */
    line-height: 1.04;
  }
  /* card titles, headings or not: the reference's post titles (the spans
     are named with their card, to outweigh §33's A9) */
  .rw-sec :is(.et-svc__t, .ct-route__t, .ia-link__t, .bw-timeline__h, .bw-team__name, .ew-house__name),
  .rw-sec :is(.dc-rel, .ha-cond, .dc-relhub, .et-frame) :is(.dc-rel__t, .ha-cond__t, .dc-relhub__t, .et-frame__name) {
    font-size: 1.25rem;                                             /* 20 */
    line-height: 1.04;
    text-wrap: balance;     /* at 20px some titles left one word on a line */
  }

  /* C4 · eyebrows .8rem, 10px over what they label; the small labels on
     cards .72rem. An eyebrow is a block of its own width here: as an inline
     box it sat in a line of the running text's height, 4.8px taller than
     itself. The reference sets its eyebrows on a line of 1, and they never
     wrap; many here do (a service and a place), and on 1 their two lines
     nearly touched, so they get 1.3 (1.9px more above and below a single
     line). */
  .rw-sec :is(.et-eyebrow, .ha-hero__eyebrow) {
    display: flex;
    width: fit-content;
    max-width: 100%;
    font-size: .8rem;                                               /* 12.8 */
    line-height: 1.3;
    margin-bottom: 10px;
  }
  .rw-sec :is(.dc-relhub__ey, .et-frame__brand) { font-size: .72rem; line-height: 1.2; }

  /* C5 · section heads: label, heading and intro 10px apart, 22px over
     what they introduce, the intro 1rem */
  .rw-sec :is(.et-sec-head:not(.et-sec-head--split), .et-sec-head--split > div, .row--head > .col) > * { margin-block: 0; }
  .rw-sec :is(.et-sec-head:not(.et-sec-head--split), .et-sec-head--split > div, .row--head > .col) > * + * { margin-top: 10px; }
  .rw-sec :is(.et-sec-head, .row--head) { margin-bottom: 22px; }
  .rw-sec .et-sec-head--split { gap: 10px; }
  .rw-sec .row--head:not(:has(.et-sec-head)) + .row { margin-top: 22px; }
  /* a head row after a row of cards is their footer (a note, a link or a
     button under them); its first block's margin, which spaced it from the
     cards, went with the rest of the head's: 22px, as from a head to its
     cards */
  .rw-sec .row + .row--head { margin-top: 22px; }
  .rw-sec :is(.et-lede, .dc-lead) { font-size: 1rem; line-height: 1.65; }

  /* C6 · heroes, the reference's hero card stack: label 12px over the
     heading, heading 12px over the intro (the home page's .3em), 18px
     between the blocks under them; the proof row 18px under the buttons
     with 14px inside its top edge. The intro clamp(1.02rem, .95rem +
     .35vw, 1.22rem) on 1.5 (16.57); buttons in a hero fill their row. */
  .rw-sec div:has(> :is(.ethc-hero__h, .ha-hero__h, .dc-hero__h, .ct-hero__h, .tib-hero__h, .et-hero__h, .et-h1)) > * { margin-block: 0; }
  .rw-sec div:has(> :is(.ethc-hero__h, .ha-hero__h, .dc-hero__h, .ct-hero__h, .tib-hero__h, .et-hero__h, .et-h1)) > * + * { margin-top: 18px; }
  .rw-sec div:has(> :is(.ethc-hero__h, .ha-hero__h, .dc-hero__h, .ct-hero__h, .tib-hero__h, .et-hero__h, .et-h1)) > :is(.et-eyebrow, .ha-hero__eyebrow, h1) + * { margin-top: 12px; }
  .rw-sec.ethc-hero .ethc-hero__copy > .ethc-hero__h { margin-bottom: .3em; }
  .rw-sec.ethc-hero .ethc-hero__copy > .ethc-hero__h + * { margin-top: 0; }
  .rw-sec.dc-hero .dc-hero__copy > .dc-hero__sub + p { margin-top: .6em; }
  .rw-sec div:has(> :is(.ethc-hero__h, .dc-hero__h)) > :is(.ethc-hero__proof, .dc-proof) { margin-top: 18px; padding-top: 14px; }
  .rw-sec :is(.ethc-hero__sub, .ha-hero__sub, .dc-hero__sub, .ct-hero__sub, .tib-hero__sub, .et-hero__sub, .bw-founder__lede),
  .rw-sec.dc-hero .dc-hero__copy > .dc-hero__sub + p,
  .rw-sec div:has(> .et-h1) > .et-lede {
    font-size: clamp(1.02rem, .95rem + .35vw, 1.22rem);             /* 16.57 */
    line-height: 1.5;
  }
  .rw-sec div:has(> :is(.ethc-hero__h, .ha-hero__h, .dc-hero__h, .ct-hero__h, .tib-hero__h, .et-hero__h)) > :is(.et-cta-cluster, .ha-hero__cta) > .btn {
    flex: 1 1 auto;
    justify-content: center;
  }
  /* the photo hero keeps its label and heading in one block and its intro
     and buttons in another: the same stack across the two */
  .rw-sec.ha-hero .ha-hero__side { margin-top: 12px; }
  .rw-sec.ha-hero .ha-hero__side > * { margin-block: 0; }
  .rw-sec.ha-hero .ha-hero__side > * + * { margin-top: 18px; }
  .rw-sec.ha-hero .ha-hero__cta > .btn { flex: 1 1 auto; justify-content: center; }
  /* a centred head's text is left-aligned on a phone; its buttons were
     centred by the source's inline style, out of line with the text above
     (unseen while every button was full width) */
  .rw-sec .et-sec-head--center > .et-cta-cluster { justify-content: flex-start !important; }
  /* the topic chips in the guide and reviews heroes: 18px under the intro
     like the other blocks (24px of empty padding sat over them), their
     label 10px over them */
  .rw-sec .tib-toolbar { padding-top: 0; }
  .rw-sec .tib-toolbar__label { margin-bottom: 10px; }
  /* the About page's hero is one grid of its copy and portrait: 18px
     between them, the label 12px over the heading, the buttons filling
     their row */
  .rw-sec.od-hero .bw-founder { row-gap: 18px; }
  .rw-sec.od-hero .bw-founder__copy > * { margin-block: 0; }
  .rw-sec.od-hero .bw-founder__copy > .bw-founder__h { margin-top: -6px; }
  .rw-sec.od-hero .bw-founder__copy > .et-cta-cluster > .btn { flex: 1 1 auto; justify-content: center; }

  /* C7 · buttons .95rem on a line of 1, padded .92em 1.45em, at least 52px;
     a row of them 14px down and 16px across, 18px under the text before it.
     Outside a hero a button is as wide as its label. */
  .rw-sec .btn {
    min-height: 52px;
    padding: .92em 1.45em;
    font-size: .95rem;                                              /* 15.2 */
    line-height: 1;
    gap: .6em;
  }
  /* layout.css keeps the source's 14.28px 26.88px for large buttons with
     !important, so this padding needs it too */
  .rw-sec a.btn.btn-lg { padding: .92em 1.45em !important; }
  .rw-sec :is(.et-cta-cluster, .ha-hero__cta) { gap: 14px 16px; }
  .rw-sec .et-cta-cluster { margin-top: 18px; }

  /* C8 · chips .76rem, padded .75em at the sides, 22.9px tall on one line,
     icons 1.2em; rows of them wrap, 8px apart. The reference's .36em above
     and below on a line of 1 gives 22.9px; its chips are one word or two,
     and some here wrap to two lines, which on 1 nearly touched. So the line
     is 1.25 and the padding .2344em: the same 22.9px for one line. */
  .rw-sec :is(span.et-pill, li.et-pill, .tib-chip, .ethc-point, .tib-point, .ethc-plan, .ethc-menu__chip, .et-frame__tag) {
    min-height: 0;
    padding: .2344em .75em;
    font-size: .76rem;                                              /* 12.16 */
    line-height: 1.25;
    gap: 6px;
  }
  .rw-sec :is(span.et-pill, li.et-pill, .tib-chip, .ethc-point, .tib-point, .ethc-plan, .ethc-menu__chip, .et-frame__tag) > svg {
    width: 1.2em;
    height: 1.2em;
  }
  .rw-sec :is(.et-chips, .dc-cap__list, .tib-creed__chips, .ethc-points, .tib-fit__points, .tib-chips, .ethc-plans, .ethc-menu) {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
  }

  /* C9 · cards, the reference's 32px glass: an info card 22px all round
     with 10px between its parts, a bigger panel 22px 20px with 12px;
     reviews 26px 24px 24px with 14px; a photo card's text 20px 22px 24px
     with 10px */
  .rw-sec :is(.dc-rel, .dc-relhub, .ha-cond, .et-svc, .ia-link, .ct-route, .ia-callout, .bw-legal__callout, .bw-toc) {
    padding: 22px;
    border-radius: 32px;
    gap: 10px;
  }
  .rw-sec :is(.ia-panel, .dc-visit, .od-close__info) {
    padding: 22px 20px;
    border-radius: 32px;
    gap: 12px;
  }
  /* the home page's comparison rows and the About page's timeline entries
     are cards too (the entry's hover state has its own padding rule) */
  .rw-sec .ethc-why__row { padding: 22px; border-radius: 32px; }
  .rw-sec .bw-timeline__entry,
  .rw-sec .bw-timeline__entry:hover { --tl-pad-x: 22px; padding: 22px var(--tl-pad-x); border-radius: 32px; }
  .rw-sec .et-review {
    padding: 26px 24px 24px;
    border-radius: 32px;
    gap: 14px;
  }
  .rw-sec .et-review__q { font-size: 1.02rem; line-height: 1.6; }
  .rw-sec .et-review__name { font-size: .98rem; line-height: 1.2; }
  .rw-sec .et-frame { border-radius: 32px; }
  .rw-sec .et-frame__body { padding: 20px 22px 24px; gap: 10px; }
  /* the gap is the space between a card's parts, as in the reference: the
     parts' own margins go (a heading's .42em, a paragraph's 1.05em, a list's
     24px, the photo cards' 14px over their link), the visit card stacks
     its name, rows and map with its gap, and the grouped text in two cards
     takes the card's 10px */
  .rw-sec :is(.dc-rel, .dc-relhub, .ha-cond, .et-svc, .ia-link, .ct-route, .ia-panel, .dc-visit, .et-frame__body) > * { margin-block: 0; }
  .rw-sec .dc-visit { display: flex; flex-direction: column; }
  .rw-sec :is(.dc-relhub__txt, .ha-cond__body) { gap: 10px; }
  .rw-sec :is(.dc-relhub__txt, .ha-cond__body) > * { margin-block: 0; }
  .rw-sec .et-frame__foot { padding-top: 0; }

  /* C10 · tiles (the hero proof, the stats): padded 10px 14px, 14px
     corners, 4px between a 1.5rem figure and its .75rem label, 10px apart */
  .rw-sec :is(.dc-proof__i, .et-stat, .ethc-hero__stat, .ia-stat) {
    display: grid;
    align-content: start;
    padding: 10px 14px;
    border-radius: 14px;
    gap: 4px;
  }
  .rw-sec :is(.dc-proof__k, .et-stat__k, .ethc-hero__k, .ia-stat__k) { font-size: 1.5rem; line-height: 1; }
  .rw-sec :is(.dc-proof__l, .et-stat__l, .ethc-hero__l, .ia-stat__l) { margin-top: 0; font-size: .75rem; line-height: 1.3; }
  .rw-sec.ethc-hero .ethc-hero__proof,
  .rw-sec.et-doctor .et-doctor__stats { gap: 10px; }
  /* the home hero's three tiles keep §22's equal columns, at these sizes
     (§22's own are named with the hero, so these are too) */
  .rw-sec.ethc-hero .ethc-hero__stat { padding: 10px 14px; gap: 4px; }
  .rw-sec.ethc-hero .ethc-hero__k { font-size: 1.5rem; line-height: 1; }
  .rw-sec.ethc-hero .ethc-hero__l { font-size: .75rem; line-height: 1.3; }
  .rw-sec.et-doctor .et-doctor__stats { margin-top: 18px; }
  /* the caption chips on the hero photos: 8px 12px, 12px corners */
  .rw-sec :is(.dc-chip, .tib-hero__chip) { padding: 8px 12px; border-radius: 12px; }
  /* photos inside the gutter take the reference's 32px frame corners, as
     the framed photos here already do (these were square) */
  .rw-sec :is(.ha-media, .ha-visit__media, .tib-fit__media, .ethc-trust__photo) { border-radius: 32px; overflow: hidden; }
  /* the eyewear page's fitting-bench photo carries the source's inline
     border-radius: var(--ds-r-surface), a token no stylesheet defines */
  .rw-sec .row--split-media > .col > img { --ds-r-surface: 32px; }

  /* C11 · FAQ: cards 14px apart with 22px corners, the question 20px 22px
     at clamp(1.02rem, .98rem + .3vw, 1.2rem) on 1.3 with 18px to its 34px
     +/-, the answer 0 22px 22px */
  .rw-sec .dc-faq__item { padding: 0; margin: 0; border-radius: 22px; }
  .rw-sec .dc-faq__item + .dc-faq__item { margin-top: 14px; }
  .rw-sec .dc-faq__item > summary {
    padding: 20px 22px;
    font-size: clamp(1.02rem, .98rem + .3vw, 1.2rem);               /* 16.85 */
    line-height: 1.3;
    gap: 18px;
  }
  .rw-sec .dc-faq__item > .dc-faq__a { padding: 0 22px 22px; }
  .rw-sec .dc-faq__ic { width: 34px; height: 34px; }

  /* C12 · rows and lists: a split row's columns 24px apart; prose lists
     indented 1.3em with .35em around each item; the site's own lists 10px
     between items; the hairline rows 8px above and below their text */
  .rw-sec .row--split { row-gap: 24px; }
  .rw-sec .dc-prose > :is(ul, ol):not([class]) { padding-left: 1.3em; }
  .rw-sec .dc-prose > :is(ul, ol):not([class]):not([style*="display:grid"]) > li { margin-block: .35em; }
  .rw-sec :is(.dc-steps, .dc-steplist, .dc-cap__steps, .dc-cap__ul, .dc-worries, .od-facts, .ia-bring) { row-gap: 10px; }
  .rw-sec :is(.dc-visit__row, .ha-nap__row, .ct-hours__row) { padding-block: 8px; }
}
