/* =================================================================
   THE PRECINCT v2 — luxury residential publication theme
   -----------------------------------------------------------------
   Manrope (rounder sans) primary, Newsreader italic reserved for
   page-title emphasis (matched x-height with the sans). Cream paper
   from v1, terracotta accent, multi-colour icon chips for wayfinding.
   Frosted-glass pill (one component, contextual styling).
   Wide diffuse sheen on image-bg cards. Mobile-first throughout.
   ================================================================= */

/* 1. Reset */
*,*::before,*::after { box-sizing: border-box; margin: 0; padding: 0; }
img, svg { display: block; max-width: 100%; }
button { font: inherit; cursor: pointer; background: none; border: 0; color: inherit; }
a { color: inherit; }

/* 2. Tokens */
:root {
  /* Palette — matched to v1 */
  --bone:      #f5f3ef;
  --bone-soft: #F8F4ED;
  --bone-dark: #eceae5;
  --paper:     #FFFFFF;
  /* Page canvas — a clean off-white that the bone hero gradient fades into.
     Slightly warmer than pure white but readable as off-white against
     bone (#f5f3ef). */
  --canvas:    #faf9f5;
  --ink:       #1a1916;
  --ink-mid:   #4B4742;
  --stone:     #8A847C;
  --rule:      #d4d0ca;
  --rule-soft: #e2ddd3;
  --rule-faint: rgba(45, 35, 25, 0.06);
  --noir:      #1a1612;

  /* Accent — terracotta */
  --acc:       #B85C1E;
  --acc-deep:  #8A3F0F;
  --acc-soft:  #EBDDC8;

  /* Multi-colour icon tones — darker for better legibility on the lighter chips */
  --tone-sage:  #4F6649;
  --tone-slate: #3D5A82;
  --tone-rose:  #8E5763;
  --tone-terra: #8A3F0F;
  --tone-clay:  #80523A;
  --tone-amber: #8A5A14;

  /* Chip backgrounds — lifted ~5% so the icon shows more clearly */
  --chip-sage:  #ECEFE7;
  --chip-slate: #E7ECF2;
  --chip-rose:  #F1E8E9;
  --chip-terra: #F0E5D5;
  --chip-clay:  #EEE4D5;
  --chip-amber: #F1E7D7;

  /* Section tints (residents guide) — washed out, mostly cream-leaning */
  --tint-parchment:        #f3ecdb;
  --tint-aqua:             #e6ede9;
  --tint-lavender:         #e8e2ed;
  --tint-rose:             #f1e5e5;
  --tint-parchment-text:   #6f5634;
  --tint-aqua-text:        #166e68;
  --tint-lavender-text:    #3d3590;
  --tint-rose-text:        #7c2c44;
  /* Slightly deeper variant of each tint — used for dividers and tags */
  --tint-parchment-rule:   #e3d6b8;
  --tint-aqua-rule:        #c8d6cd;
  --tint-lavender-rule:    #cec3d8;
  --tint-rose-rule:        #e0c5c5;
  /* Cool, less-yellow panel tint for Something Missing / Get in Touch panels */
  --panel-bg:              #f1efea;

  /* Safety palette — pulled from v1, washed-out warm red */
  --safety-bg:             #faf2f0;
  --safety-bg-soft:        #f5e6e0;
  --safety-rule:           #eaccc4;
  --safety-rule-soft:      #f0d9d2;
  --safety-text:           #9a2810;
  --safety-text-deep:      #6a1808;

  /* SAT v1-matched colours */
  --sat-amber-bg:    #fdf3e3;
  --sat-amber-border: #e8c870;
  --sat-amber-text:  #7a5010;
  --sat-blue-bg:     #e8f2fa;
  --sat-blue-border: #90b8d8;
  --sat-blue-text:   #1a4a6a;
  --sat-red-note-bg: #fef0f0;
  --sat-red-note-border: #f0b8b8;
  --sat-red-note-text: #5a2020;
  --sat-red-pill-bg: #fce8e8;
  --sat-red-pill-text: #a03030;

  /* Type families */
  --font-sans:   'Mulish', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
  --font-italic: 'IBM Plex Serif', Georgia, 'Times New Roman', serif;
  --font-mono:   'JetBrains Mono Variable', 'JetBrains Mono', ui-monospace, 'SF Mono', monospace;

  /* Type sizes (mobile-first) */
  --fz-h1: clamp(1.85rem, 6vw, 2.6rem);
  --fz-h2: clamp(1.4rem, 4.4vw, 1.85rem);
  --fz-h3: clamp(1.15rem, 3vw, 1.4rem);
  --fz-h4: 1.05rem;

  /* Tweakable knobs (locked from the picker tool) */
  --nav-glass-alpha:    0.85;
  --pill-glass-alpha:   0.55;
  --pill-padding-y:     8px;
  --pill-padding-x:     14px;
  --pill-fz:            9.5px;
  --pill-bg-rgb:        232, 230, 228;     /* cool stone — replaces yellowish cream */

  /* Promo gradient — 5-stop curve. Locked values from picker. */
  --promo-overlay-top:   0;
  --promo-top-stop:      10%;
  --promo-bot-start:     34%;
  --promo-bot-mid:       66%;
  --promo-bot-mid-alpha: 0.56;
  --promo-overlay-bot:   0.78;
  --promo-h-fz:          1.6rem;

  /* Layout */
  --container:        980px;
  --container-narrow: 720px;
  --container-pad:    1.15rem;
  --band-py:          clamp(2rem, 7vw, 4rem);
  --band-py-sm:       clamp(1.5rem, 5vw, 2.5rem);
  --hero-py:          clamp(2rem, 6vw, 3.75rem);
  --nav-h:            58px;

  /* Radii */
  --r:    4px;
  --r-md: 6px;
  --r-lg: 12px;
}

@media (min-width: 720px) {
  :root { --container-pad: 1.5rem; }
}

/* 3. Type primitives */
html { background: var(--canvas); -webkit-text-size-adjust: 100%; }
body {
  font-family: var(--font-sans);
  font-weight: 400;
  font-size: 0.95rem;
  line-height: 1.6;
  color: var(--ink);
  background: var(--canvas);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  display: flex;
  flex-direction: column;
  min-height: 100dvh;
}

/* Italic emphasis — IBM Plex Serif italic. Plex Serif has a smaller x-height
   than Mulish; nudge size for body but trim it back inside heroes/h1s where
   the larger glyph sizes make Plex feel oversized next to Mulish. */
.lux-em {
  font-family: var(--font-italic);
  font-style: italic;
  font-weight: 400;
  color: var(--acc);
  letter-spacing: 0;
  font-size: 1.04em;
}
.lux-hero h1 .lux-em,
.lux-hero h2 .lux-em,
h1 .lux-em,
h2 .lux-em {
  font-size: 0.95em;
  /* Optical alignment — Plex Serif italic sits slightly higher than Mulish */
  vertical-align: -0.01em;
}

/* Headings — pulled left by ~0.025em so their optical edge lines up with
   the eyebrow above and the description prose below (negative letter-spacing
   otherwise tucks the first character slightly inside the column). */
.lux-h1 { font-family: var(--font-sans); font-weight: 500; letter-spacing: -0.02em; line-height: 1.05; color: var(--ink); font-size: var(--fz-h1); text-wrap: balance; margin-left: -0.025em; }
.lux-h2 { font-family: var(--font-sans); font-weight: 500; letter-spacing: -0.02em; line-height: 1.08; color: var(--ink); font-size: var(--fz-h2); text-wrap: balance; margin-left: -0.025em; }
.lux-h3 { font-family: var(--font-sans); font-weight: 500; letter-spacing: -0.018em; line-height: 1.12; color: var(--ink); font-size: var(--fz-h3); margin-left: -0.02em; }
.lux-h4 { font-family: var(--font-sans); font-weight: 500; letter-spacing: -0.014em; line-height: 1.18; color: var(--ink); font-size: var(--fz-h4); margin-left: -0.015em; }

.lux-eye {
  display: inline-block;
  font-size: 10.5px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--stone);
  font-weight: 500;
  margin-bottom: 11px;
}

.lux-prose { font-size: 0.95rem; color: var(--ink-mid); line-height: 1.65; }
.lux-prose-sm { font-size: 0.88rem; color: var(--ink-mid); line-height: 1.6; }
.lux-prose strong, .lux-prose-sm strong { color: var(--ink); font-weight: 600; }
.lux-prose a, .lux-prose-sm a { color: var(--acc); text-decoration: underline; text-underline-offset: 3px; text-decoration-thickness: 1px; }
.lux-prose a:hover, .lux-prose-sm a:hover { color: var(--acc-deep); }
.lux-prose p + p, .lux-prose-sm p + p { margin-top: 0.85em; }

/* 4. Layout */
.lux-container { width: 100%; max-width: var(--container); margin: 0 auto; padding: 0 var(--container-pad); }
.lux-container--narrow { max-width: var(--container-narrow); }

.lux-band { padding: var(--band-py) 0; position: relative; }
.lux-band--sm { padding: var(--band-py-sm) 0; }
/* Neutral sections all sit on the page canvas — no alternation. The home
   channel strip uses .lux-channels-band to keep its distinct cream tone. */
.lux-band--bone     { background: transparent; }
.lux-band--paper    { background: transparent; }
.lux-band--soft     { background: transparent; }
.lux-band--canvas   { background: transparent; }
.lux-band--bone-dark { background: var(--bone-dark); }

/* Channels strip on the home page — kept distinct as a warm bone band. */
.lux-channels-band { background: var(--bone); padding: 0.5rem 0; }

/* Section tints — every tint variant sits on the standard page bg.
   The colour comes through inside the accordion card (see scoped rules
   below) and via --section-text / --section-rule on tags + dividers.
   The .lux-band--tint-residents wrapper applies a subtle parchment-tone
   page bg for the resident guide; the safety variants share the paler
   safety bg so the whole guide reads as one warm wash. */
.lux-band--tint-parchment { background: transparent; --section-rule: var(--tint-parchment-rule); --section-text: var(--tint-parchment-text); --section-soft: var(--tint-parchment); }
.lux-band--tint-aqua      { background: transparent; --section-rule: var(--tint-aqua-rule);      --section-text: var(--tint-aqua-text);      --section-soft: var(--tint-aqua); }
.lux-band--tint-lavender  { background: transparent; --section-rule: var(--tint-lavender-rule);  --section-text: var(--tint-lavender-text);  --section-soft: var(--tint-lavender); }
.lux-band--tint-rose      { background: transparent; --section-rule: var(--tint-rose-rule);      --section-text: var(--tint-rose-text);      --section-soft: var(--tint-rose); }
.lux-band--tint-safety    { background: var(--safety-bg); --section-rule: var(--safety-rule);     --section-text: var(--safety-text);         --section-soft: var(--safety-bg-soft); }
.lux-band--tint-safety-soft { background: var(--safety-bg); --section-rule: var(--safety-rule-soft); --section-text: var(--safety-text);     --section-soft: var(--safety-bg-soft); }

/* Inside any tinted section, dividers + indicators reflect the section colour */
[class*="lux-band--tint-"] .lux-acc                       { border-top-color: var(--section-rule); }
[class*="lux-band--tint-"] .lux-acc-it                    { border-bottom-color: var(--section-rule); }
[class*="lux-band--tint-"] .lux-acc-it:last-child         { border-bottom-color: var(--section-rule); }
[class*="lux-band--tint-"] .lux-acc-ind                   { color: var(--section-text); opacity: 0.65; }
[class*="lux-band--tint-"] .lux-acc-it.is-open .lux-acc-ind { color: var(--section-text); opacity: 1; }

/* Section icon chip inside a tinted section — washed-out section bg with
   the section text colour for the icon and a soft section-coloured border. */
[class*="lux-band--tint-"] .lux-section-icon-chip {
  background:
    linear-gradient(rgba(255, 255, 255, 0.55), rgba(255, 255, 255, 0.55)),
    var(--section-rule);
  color: var(--section-text);
  border: 1px solid var(--section-rule);
}

/* Accordion list inside a residents-guide tinted section becomes a rounded,
   softly coloured card so the colour reads as the accordion's home rather
   than the whole section. Safety sections already wash the section bg, so
   they keep a flat accordion. */
.lux-band--tint-parchment .lux-acc,
.lux-band--tint-aqua      .lux-acc,
.lux-band--tint-lavender  .lux-acc,
.lux-band--tint-rose      .lux-acc {
  background:
    linear-gradient(rgba(255, 255, 255, 0.55), rgba(255, 255, 255, 0.55)),
    var(--section-rule);
  border: 1px solid var(--section-rule);
  border-radius: var(--r-md);
  padding: 0 1.1rem;
  border-top-color: var(--section-rule);
}
.lux-band--tint-parchment .lux-acc-it,
.lux-band--tint-aqua      .lux-acc-it,
.lux-band--tint-lavender  .lux-acc-it,
.lux-band--tint-rose      .lux-acc-it { border-bottom-color: var(--section-rule); }
.lux-band--tint-parchment .lux-acc-it:last-child,
.lux-band--tint-aqua      .lux-acc-it:last-child,
.lux-band--tint-lavender  .lux-acc-it:last-child,
.lux-band--tint-rose      .lux-acc-it:last-child { border-bottom: 0; }

/* Hollow tags inside a tinted section — fully transparent so the section's
   wash shows through; the section-rule outline carries the colour. */
[class*="lux-band--tint-"] .lux-tag--hollow,
[class*="lux-band--tint-"] .lux-acc-tag--stone {
  background: transparent;
  border-color: var(--section-rule);
}

/* Inside a tinted section, the body pills (button-style) follow the section
   colour with a soft white-tinted bg for contrast. Tag labels (.lux-acc-tag,
   .lux-tag) automatically inherit --section-text via the rules in 5b. */
[class*="lux-band--tint-"] .lux-acc-body .lux-pill {
  background: rgba(255, 255, 255, 0.55);
  border-color: var(--section-rule);
  color: var(--section-text);
}
[class*="lux-band--tint-"] .lux-acc-body .lux-pill:hover {
  background: rgba(255, 255, 255, 0.85);
  border-color: var(--section-text);
}
[class*="lux-band--tint-"] .lux-acc-body .lux-pill .lux-ic { color: var(--section-text); }

.lux-hr { height: 1px; background: var(--rule); border: 0; margin: 0; }

/* 5. Frosted glass pill */
.lux-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: var(--pill-padding-y) var(--pill-padding-x);
  border-radius: 100px;
  background: rgba(var(--pill-bg-rgb), var(--pill-glass-alpha));
  -webkit-backdrop-filter: blur(14px) saturate(180%);
          backdrop-filter: blur(14px) saturate(180%);
  border: 1px solid rgba(45, 40, 36, 0.14);
  color: #1B1B16;
  font-size: var(--pill-fz);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  font-weight: 500;
  text-decoration: none;
  position: relative;
  isolation: isolate;
  transition: background 0.2s ease, border-color 0.2s ease, color 0.2s ease;
}
.lux-pill:hover { background: rgba(var(--pill-bg-rgb), calc(var(--pill-glass-alpha) + 0.25)); border-color: rgba(45, 40, 36, 0.26); }
.lux-pill .lux-ic { color: var(--acc); }

/* Section-header pill — used at the top of a section to take the user to
   the full version of that index. Toasted bone bg with bright off-white
   writing for clear contrast. */
.lux-pill--section {
  background: #9c8e78;
  border-color: #8a7d68;
  color: var(--paper);
}
.lux-pill--section:hover {
  background: #847864;
  border-color: #6f6453;
  color: var(--paper);
}
.lux-pill--section .lux-ic { color: var(--paper); }

/* Pill on dark / image */
.on-dark .lux-pill,
.lux-promo .lux-pill {
  background: rgba(245, 240, 232, 0.14);
  border-color: rgba(255, 255, 255, 0.2);
  color: var(--bone);
}
.on-dark .lux-pill:hover,
.lux-promo .lux-pill:hover { background: rgba(245, 240, 232, 0.28); border-color: rgba(255, 255, 255, 0.36); }
.on-dark .lux-pill .lux-ic, .lux-promo .lux-pill .lux-ic { color: var(--bone); }

/* 5b. Tag — rounded rectangle label (sits next to titles or as status chips).
   Two variants: --solid for key information, --hollow for location/context.
   Always picks up --section-text / --section-rule when scoped inside a tinted
   section, otherwise falls back to ink/stone. */
.lux-tag {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  padding: 4px 8px;
  border-radius: 4px;
  vertical-align: middle;
  line-height: 1;
}
/* Solid tag — key information. Soft section-coloured fill (section rule
   washed back to ~45% over white) + section-coloured text + a section-rule
   outline for definition. */
.lux-tag--solid {
  background:
    linear-gradient(rgba(255, 255, 255, 0.45), rgba(255, 255, 255, 0.45)),
    var(--section-rule, var(--bone-dark));
  color: var(--section-text, var(--ink));
  border: 1px solid var(--section-rule, var(--rule));
}
/* Hollow tag — location/context (e.g. 'Stage 1', 'Stage 2'). No fill at all
   so the page bg shows through, just a section-coloured outline + text. */
.lux-tag--hollow {
  background: transparent;
  color: var(--section-text, var(--ink-mid));
  border: 1px solid var(--section-rule, var(--rule));
}

/* 6. Sheen — codeguage classic shimmer (background-position-based, -45deg).
   Faster swipe, longer gap between cycles, shorter trailing edge,
   ~30% more transparent than the previous pass. */
.lux-sheen {
  position: relative;
  overflow: hidden;
  isolation: isolate;
}
.lux-sheen::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(
    -45deg,
    transparent 46%,
    rgba(255, 255, 255, 0.29) 50%,
    transparent 54%
  );
  background-size: 300% 300%;
  background-position: 100% 100%;
  pointer-events: none;
  z-index: 4;
  animation: lux-sheen 7s cubic-bezier(0.4, 0, 0.2, 1) infinite;
  animation-delay: var(--d, 0s);
}
@keyframes lux-sheen {
  0%, 65% { background-position: 100% 100%; }
  100%    { background-position: 0% 0%; }
}

@media (prefers-reduced-motion: reduce) {
  .lux-pill--glow::before,
  .lux-sheen::after { animation: none; }
}

/* 7. Icons */
.lux-ic { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 1.2; stroke-linecap: round; stroke-linejoin: round; flex-shrink: 0; }
.lux-ic--sm { width: 13px; height: 13px; }
.lux-ic--lg { width: 22px; height: 22px; }

.lux-chip {
  width: 36px; height: 36px;
  border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  flex-shrink: 0;
  background: var(--chip);
  color: var(--tone);
}
.lux-chip--sm { width: 32px; height: 32px; }
.lux-chip--lg { width: 40px; height: 40px; }

.t-sage  { --tone: var(--tone-sage);  --chip: var(--chip-sage); }
.t-slate { --tone: var(--tone-slate); --chip: var(--chip-slate); }
.t-rose  { --tone: var(--tone-rose);  --chip: var(--chip-rose); }
.t-terra { --tone: var(--tone-terra); --chip: var(--chip-terra); }
.t-clay  { --tone: var(--tone-clay);  --chip: var(--chip-clay); }
.t-amber { --tone: var(--tone-amber); --chip: var(--chip-amber); }
.t-parchment { --tone: var(--tint-parchment-text); --chip: var(--tint-parchment); }
.t-aqua-tint { --tone: var(--tint-aqua-text);      --chip: var(--tint-aqua); }
.t-lavender  { --tone: var(--tint-lavender-text);  --chip: var(--tint-lavender); }
.t-rose-tint { --tone: var(--tint-rose-text);      --chip: var(--tint-rose); }

/* 8. Channel cells — no outer top/bottom rules (clean entry/exit) */
.lux-channels {
  display: grid;
  /* auto-fit so the grid collapses cleanly when channel cards are
     added or removed (e.g. forum is currently hidden, leaving 2 cards). */
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
}
.lux-channel { padding: 1.4rem 1.15rem 1.5rem; display: flex; flex-direction: column; }
.lux-channel + .lux-channel { border-left: 1px solid var(--rule-faint); }
.lux-channel-icon { margin-bottom: 14px; }
.lux-channel-name { font-weight: 600; font-size: clamp(1.22rem, 3vw, 1.32rem); letter-spacing: -0.022em; line-height: 1.18; margin-bottom: 8px; color: var(--ink); }
.lux-channel-desc { font-size: 0.92rem; color: var(--ink-mid); line-height: 1.55; margin-bottom: 16px; flex: 1; }
.lux-channel-pills { display: flex; flex-wrap: wrap; gap: 8px; align-self: flex-start; }
.lux-channel-pills .lux-pill--mobile { display: inline-flex; }
.lux-channel-pills .lux-pill--desktop { display: none; }
@media (min-width: 701px) {
  .lux-channel-pills .lux-pill--mobile { display: none; }
  .lux-channel-pills .lux-pill--desktop { display: inline-flex; }
}
@media (max-width: 700px) {
  .lux-channels { grid-template-columns: 1fr; }
  .lux-channel + .lux-channel { border-left: 0; border-top: 1px solid var(--rule-faint); }
  .lux-channel { padding: 1.05rem 1rem 1.15rem; }
  .lux-channel-icon { margin-bottom: 10px; }
  .lux-channel-name { font-size: 1.18rem; margin-bottom: 5px; }
  .lux-channel-desc { font-size: 0.88rem; margin-bottom: 11px; }
}

/* 9. Accordion */
/* Top, between-item and bottom rules all share the same faint colour. */
.lux-acc { border-top: 1px solid var(--rule-faint); }
.lux-acc-it { border-bottom: 1px solid var(--rule-faint); }
.lux-acc-it:last-child { border-bottom: 1px solid var(--rule-faint); }
.lux-acc-head {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  padding: 1.1rem 0;
  text-align: left;
}
.lux-acc-tw { display: flex; align-items: center; gap: 14px; min-width: 0; flex: 1; }
.lux-acc-title {
  font-size: 1.02rem;
  font-weight: 600;
  letter-spacing: -0.018em;
  line-height: 1.22;
  color: var(--ink);
  display: inline-flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
}
/* Accordion-title tag — same washed-out solid as .lux-tag--solid. */
.lux-acc-tag {
  display: inline-flex;
  align-items: center;
  font-size: 9.5px; font-weight: 600; letter-spacing: 0.16em; text-transform: uppercase;
  padding: 4px 8px; border-radius: 4px;
  background:
    linear-gradient(rgba(255, 255, 255, 0.45), rgba(255, 255, 255, 0.45)),
    var(--section-rule, var(--bone-dark));
  color: var(--section-text, var(--ink));
  border: 1px solid var(--section-rule, var(--rule));
  line-height: 1;
}
.lux-acc-tag--stone {
  background: transparent;
  color: var(--section-text, var(--ink-mid));
  border: 1px solid var(--section-rule, var(--rule));
}
.lux-acc-tag--terra { background: var(--acc-soft); color: var(--acc-deep); border-color: var(--acc); }
.lux-acc-ind {
  font-size: 1.2rem;
  color: var(--stone);
  line-height: 1;
  flex-shrink: 0;
  font-weight: 300;
  align-self: center;
  transition: transform 0.25s ease, color 0.2s ease;
}
.lux-acc-it.is-open .lux-acc-ind { transform: rotate(45deg); color: var(--acc); }
/* Body breathes open/close. JS measures the actual content height
   and writes inline max-height so the transition runs to the real
   height rather than a generic ceiling. The CSS rule below is a
   no-JS fallback (90rem still produces an animation, just slightly
   off-pace). Opacity transitions in/out faster than height so the
   text fades in once the row is partway open and fades out
   immediately when closing. */
.lux-acc-body {
  max-height: 0;
  overflow: hidden;
  opacity: 0;
  padding: 0 0 0 0;
  font-size: 0.92rem;
  color: var(--ink-mid);
  line-height: 1.65;
  transition: max-height 0.4s cubic-bezier(0.32, 0.72, 0, 1),
              opacity 0.2s ease,
              padding 0.36s cubic-bezier(0.32, 0.72, 0, 1);
}
.lux-acc-it.is-open .lux-acc-body {
  max-height: 90rem;
  opacity: 1;
  padding: 0.5rem 0 1.25rem 0;
  /* Tiny delay on the fade-in so it follows just behind the height,
     reading as content arriving INTO an opening row. */
  transition: max-height 0.4s cubic-bezier(0.32, 0.72, 0, 1),
              opacity 0.18s ease 0.06s,
              padding 0.36s cubic-bezier(0.32, 0.72, 0, 1);
}
@media (prefers-reduced-motion: reduce) {
  .lux-acc-body { transition: none; }
}
.lux-acc-body p + p { margin-top: 0.75em; }
.lux-acc-body strong { color: var(--ink); font-weight: 600; }
.lux-acc-body a { color: var(--acc); text-decoration: underline; text-underline-offset: 3px; }
.lux-acc-body .lux-pill { margin-top: 0.85rem; text-decoration: none !important; }
.lux-acc-body .lux-pill { background: rgba(var(--pill-bg-rgb), var(--pill-glass-alpha)); }

/* 10. Image-bg promo */
.lux-promo {
  display: block;
  position: relative;
  aspect-ratio: 4/5;
  background-size: cover;
  background-position: center;
  border-radius: var(--r-md);
  overflow: hidden;
  isolation: isolate;
  text-decoration: none;
  color: var(--bone);
}
.lux-promo--wide { aspect-ratio: 16/10; }
.lux-promo::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background: linear-gradient(180deg,
    rgba(11,11,8,var(--promo-overlay-top)) 0%,
    rgba(11,11,8,0) var(--promo-top-stop),
    rgba(11,11,8,0) var(--promo-bot-start),
    rgba(11,11,8,var(--promo-bot-mid-alpha)) var(--promo-bot-mid),
    rgba(11,11,8,var(--promo-overlay-bot)) 100%);
}
.lux-promo-cap { position: absolute; left: 16px; right: 16px; bottom: 16px; z-index: 3; }
.lux-promo-eye {
  font-family: var(--font-sans);
  font-size: 10.5px;
  font-weight: 500;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: rgba(245,240,232,0.85);
  margin-bottom: 4px;
}
.lux-promo-h {
  font-weight: 500;
  font-size: var(--promo-h-fz);
  letter-spacing: -0.025em;
  line-height: 1.04;
  margin-bottom: 18px;
  color: var(--bone);
}
.lux-promo-h .lux-em { color: var(--bone); }
.lux-promo-actions { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 0; }
@media (min-width: 720px) {
  .lux-promo--wide { aspect-ratio: 16/10; }
  .lux-promo-cap { left: 22px; right: 22px; bottom: 22px; }
  .lux-promo-h { font-size: 1.65rem; }
}

/* 11. Promo grid — promo cards adopt the wide aspect (16/10) so they match
   the home-page resident-guide promo's mobile height. Two-column grid on
   tablet and up. */
.lux-promo-grid { display: grid; grid-template-columns: 1fr; gap: 12px; }
.lux-promo-grid .lux-promo { aspect-ratio: 16/10; }
@media (min-width: 720px) {
  .lux-promo-grid { grid-template-columns: 1fr 1fr; gap: 14px; }
}

/* 12. Contact card — slim, paper, no edge stripe, unified eyebrow tag */
.lux-contact {
  display: flex;
  flex-direction: column;
  background: var(--paper);
  border-radius: var(--r-md);
  border: 1px solid var(--rule);
  overflow: hidden;
  position: relative;
}
.lux-contact-header {
  padding: 0.8rem 1.05rem 0.85rem;
  border-bottom: 1px solid var(--rule-faint);
}
/* Single neutral eyebrow style across every card */
.lux-contact-role {
  display: inline-block;
  font-size: 9px; letter-spacing: 0.22em; text-transform: uppercase;
  font-weight: 600;
  padding: 3px 9px; border-radius: 4px;
  background: var(--bone-dark);
  color: var(--ink-mid);
  margin-bottom: 7px;
}
.lux-contact-name {
  font-weight: 600; font-size: 1.05rem; letter-spacing: -0.02em;
  color: var(--ink); line-height: 1.2;
}
/* Single-row contact card foot — one row spans the full width */
.lux-contact-foot {
  display: flex;
  flex-direction: row;
  align-items: stretch;
}
.lux-contact-row {
  display: flex; align-items: center; gap: 8px;
  padding: 0.65rem 0.95rem;
  font-size: 0.84rem; color: var(--ink);
  flex: 1 1 0;
  min-width: 0;
}
.lux-contact-row .lux-ic {
  width: 14px; height: 14px; flex-shrink: 0;
  color: var(--ink-mid);
  opacity: 0.85;
}
.lux-contact-action-text {
  flex: 1; min-width: 0;
  color: var(--ink); text-decoration: none;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  letter-spacing: -0.005em;
  font-feature-settings: "tnum";
  transition: color 0.15s ease;
}
.lux-contact-action-text:hover { color: var(--acc); }
.lux-contact-copy { display: none !important; }

/* Slide-toggle layout: faces stack absolutely. The visible face has
   .is-current. Each toggle slides the current face out to the LEFT and the
   incoming face in from the RIGHT — both directions move leftward.
   The JS resets the incoming face to the right WITHOUT animation before
   triggering the slide so the second toggle never bounces. */
.lux-contact-foot--slide {
  position: relative;
  overflow: hidden;
  display: block;
}
.lux-contact-deck {
  position: relative;
  width: 100%;
  min-height: 44px;
}
.lux-contact-face {
  display: flex; align-items: center;
  position: absolute;
  inset: 0;
  width: 100%;
  padding: 0.65rem 0.95rem;
  gap: 8px;
  font-size: 0.84rem; color: var(--ink);
  background: var(--paper);
  transform: translateX(100%);
  transition: transform 0.32s cubic-bezier(0.4, 0, 0.2, 1);
  will-change: transform;
}
.lux-contact-face.is-current { transform: translateX(0); }
.lux-contact-face.is-leaving { transform: translateX(-100%); }
/* JS uses .lux-contact-face--snap to position a face without animating. */
.lux-contact-face--snap { transition: none !important; transform: translateX(100%) !important; }

.lux-contact-face .lux-ic {
  width: 14px; height: 14px; flex-shrink: 0;
  color: var(--ink-mid); opacity: 0.85;
}
.lux-contact-face .lux-contact-action-text {
  flex: 1; min-width: 0;
  color: var(--ink); text-decoration: none;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  letter-spacing: -0.005em;
}
/* Toggle button on the right — shows the *other* mode's icon */
.lux-contact-toggle {
  flex: 0 0 auto;
  display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px;
  border-radius: 6px;
  background: var(--bone);
  border: 1px solid var(--rule-faint);
  color: var(--ink-mid);
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease;
}
.lux-contact-toggle:hover { background: var(--bone-dark); color: var(--acc); }
.lux-contact-toggle .lux-ic { width: 14px; height: 14px; opacity: 1; }

/* Contacts grid (multiple cards) */
.lux-contact-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 12px;
}
@media (min-width: 540px) {
  .lux-contact-grid { grid-template-columns: 1fr 1fr; gap: 14px; }
}

/* 13. List rows — top, bottom and between dividers all share --rule-faint
   for a soft, even rhythm. */
.lux-rows { border-top: 1px solid var(--rule-faint); }
.lux-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  padding: 1.15rem 0;
  border-bottom: 1px solid var(--rule-faint);
  text-decoration: none;
  color: inherit;
}
.lux-row:last-child { border-bottom: 1px solid var(--rule-faint); }
.lux-row-left { display: flex; align-items: center; gap: 14px; min-width: 0; flex: 1; }
.lux-row-name { font-weight: 600; font-size: 1.06rem; letter-spacing: -0.02em; color: var(--ink); line-height: 1.2; }
.lux-row-desc { font-size: 0.85rem; color: var(--ink-mid); line-height: 1.5; margin-top: 4px; }
.lux-row-arrow { color: var(--stone); font-size: 1.05rem; flex-shrink: 0; transition: color 0.15s ease, transform 0.15s ease; display: inline-flex; align-items: center; }
.lux-row-arrow .lux-ic { color: currentColor; }
.lux-row:hover .lux-row-arrow { color: var(--acc); transform: translateX(3px); }

/* External-link variant — colour change only on hover, no movement. Use for
   any row whose target opens off-site. */
.lux-row--ext:hover .lux-row-arrow { color: var(--acc); transform: none; }
.lux-row--ext:hover .lux-row-name { color: var(--acc); transition: color 0.15s ease; }

/* Store-pills row variant — non-link parent, keeps iOS/Android (or "Visit X")
   pills on the right at every breakpoint. */
.lux-row--store { cursor: default; }
.lux-row--store:hover { background: transparent; }
.lux-row--store .lux-app-btns { flex-shrink: 0; justify-content: flex-end; }
@media (max-width: 540px) {
  .lux-row--store {
    flex-direction: column;
    align-items: flex-end;
    gap: 10px;
  }
  .lux-row--store .lux-row-left { width: 100%; }
}

/* 14. Status pills */
.lux-stat {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 5px 12px;
  border-radius: 100px;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.04em;
  border: 1px solid;
}
.lux-stat::before { content: ''; width: 6px; height: 6px; border-radius: 50%; background: currentColor; opacity: 0.85; }
.lux-stat--no-dot::before { display: none; }
.lux-stat--blue   { color: var(--sat-blue-text);  background: var(--sat-blue-bg);  border-color: var(--sat-blue-border); }
.lux-stat--amber  { color: var(--sat-amber-text); background: var(--sat-amber-bg); border-color: var(--sat-amber-border); }
.lux-stat--rose   { color: var(--sat-red-pill-text); background: var(--sat-red-pill-bg); border-color: var(--sat-red-note-border); }
.lux-stat--stone  { color: var(--ink-mid);        background: var(--bone-dark);     border-color: var(--rule); }

/* 15. Generic card */
.lux-card { background: var(--paper); border: 1px solid var(--rule); border-radius: var(--r-md); padding: 1.4rem 1.5rem; }
.lux-card--bone { background: var(--bone-dark); }
.lux-card-eye { font-size: 9.5px; letter-spacing: 0.22em; text-transform: uppercase; color: var(--stone); font-weight: 500; margin-bottom: 9px; display: inline-block; }

/* 16. Section title pattern */
.lux-section-title {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  margin-bottom: 1.4rem;
}
.lux-section-title h2 { margin: 0; }
.lux-section-count { font-family: var(--font-mono); font-size: 0.78rem; color: var(--stone); letter-spacing: 0.04em; }

/* Section with icon (residents guide) */
.lux-section-icon {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-bottom: 1.4rem;
}
.lux-section-icon-chip {
  width: 44px; height: 44px;
  border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  flex-shrink: 0;
  background: var(--chip);
  color: var(--tone);
}
.lux-section-icon-chip svg { width: 22px; height: 22px; }

/* 17. Splitout */
.lux-split { display: grid; grid-template-columns: 1fr; border-radius: var(--r-md); overflow: hidden; border: 1px solid var(--rule); }
.lux-split-left  { padding: 1.5rem 1.6rem; background: var(--noir); color: var(--bone); }
.lux-split-right { padding: 1.5rem 1.6rem; background: var(--bone-soft); }
.lux-split-left .lux-eye { color: rgba(245,240,232,0.65); }
.lux-split-left .lux-h3, .lux-split-left h3 { color: var(--bone); }
.lux-split-left .lux-prose-sm { color: rgba(245,240,232,0.78); }
@media (min-width: 720px) { .lux-split { grid-template-columns: 1fr 1fr; } }

/* Newsletter colour variants */
.lux-split--ink   .lux-split-left { background: #1a1612; }
.lux-split--plum  .lux-split-left { background: #3a2e5c; }
.lux-split--forest .lux-split-left { background: #1f3d2e; }
.lux-split--burgundy .lux-split-left { background: #4a1f24; }
.lux-split--midnight .lux-split-left { background: #1c2438; }

/* Plum splitout — purple-harmonised internals.
   The CSS-variable override re-resolves any inline `var(--acc)`
   inside the right column to the lavender, so eyebrow + dots
   pick it up automatically. */
.lux-split--plum .lux-split-right {
  --acc: #6e5ea6;
  background: #ede8f5;
}
.lux-split--plum .lux-split-right .lux-eye { color: #4d3f88; }

.lux-split--plum .lux-split-left .lux-pill {
  background: rgba(220, 210, 245, 0.95);
  color: #1e1535;
  border-color: rgba(220, 210, 245, 0.6);
}
.lux-split--plum .lux-split-left .lux-pill:hover {
  background: #fff;
  border-color: rgba(255, 255, 255, 0.85);
  color: #1e1535;
}
.lux-split--plum .lux-split-left .lux-pill .lux-ic { color: #1e1535; }
.lux-split--plum .lux-split-left .lux-pill--ghost {
  background: transparent;
  border-color: rgba(220, 210, 245, 0.45);
  color: #d6c8f0;
}
.lux-split--plum .lux-split-left .lux-pill--ghost:hover {
  background: rgba(220, 210, 245, 0.1);
  border-color: rgba(220, 210, 245, 0.8);
  color: #fff;
}
.lux-split--plum .lux-split-left .lux-pill--ghost .lux-ic { color: #d6c8f0; }

/* 17b. Hamburger + fullscreen menu (Apple-inspired)
   ─────────────────────────────────────────────────
   Two horizontal bars that flip into an X when active. Sits at the
   right of the nav, with the App pill immediately before it. Tap opens
   a fullscreen scrollable sheet that covers the page below the nav. */
.lux-nav-right {
  display: flex; align-items: center; gap: 0.85rem;
}
.lux-menu-toggle {
  position: relative;
  width: 36px; height: 36px;
  display: inline-flex;
  align-items: center; justify-content: center;
  background: transparent;
  border: 0;
  padding: 0;
  cursor: pointer;
  color: var(--ink);
  -webkit-tap-highlight-color: transparent;
}
.lux-menu-toggle span {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 22px; height: 1.5px;
  background: currentColor;
  border-radius: 2px;
  transform-origin: 50% 50%;
  margin-left: -11px;
  /* Force a GPU compositing layer so iOS Safari uses the accelerated
     path for transform changes instead of repainting (which it
     otherwise skips/snaps to the end state). backface-visibility +
     translate3d in the transform are the two standard nudges. */
  will-change: transform;
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
  /* Both vendor-prefixed and unprefixed transition for older WebKit. */
  -webkit-transition: -webkit-transform 0.32s cubic-bezier(0.65, 0, 0.35, 1);
  transition: transform 0.32s cubic-bezier(0.65, 0, 0.35, 1),
              -webkit-transform 0.32s cubic-bezier(0.65, 0, 0.35, 1);
}
/* Two parallel bars 5.5px apart in the rest state. Both initial and open
   transforms use translate3d + rotate (matching function lists) so iOS
   Safari can interpolate between them without dropping the transition. */
.lux-menu-toggle span:first-child {
  -webkit-transform: translate3d(0, -4.5px, 0) rotate(0deg);
  transform: translate3d(0, -4.5px, 0) rotate(0deg);
}
.lux-menu-toggle span:last-child {
  -webkit-transform: translate3d(0, 3px, 0) rotate(0deg);
  transform: translate3d(0, 3px, 0) rotate(0deg);
}
/* Smoothly converge to the centre, then rotate into the X. */
.lux-menu-toggle.is-open span:first-child {
  -webkit-transform: translate3d(0, 0, 0) rotate(45deg);
  transform: translate3d(0, 0, 0) rotate(45deg);
}
.lux-menu-toggle.is-open span:last-child {
  -webkit-transform: translate3d(0, 0, 0) rotate(-45deg);
  transform: translate3d(0, 0, 0) rotate(-45deg);
}

/* Fullscreen menu drawer — apple.com mega-menu feel.
   The drawer animation uses transform: translate3d() instead of height,
   which is GPU-accelerated by mobile WebKit and stays smooth at 60fps
   on iOS. (Height/max-height transitions trigger layout every frame and
   are notoriously jerky on iOS Safari.) The drawer is full-height and
   lives translated -100% (above the viewport) when closed; toggling
   .is-open animates it down to translate3d(0,0,0). The items inside
   use opacity-only transitions for the staggered cascade — opacity is
   also GPU-accelerated and cheap to animate concurrently. */
.lux-menu {
  position: fixed;
  top: var(--nav-h); left: 0; right: 0;
  height: calc(100vh - var(--nav-h));
  background: var(--paper);
  z-index: 49;
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  /* Closed: slid up out of view. visibility removes it from the
     accessibility tree until the open animation kicks in. */
  -webkit-transform: translate3d(0, -100%, 0);
  transform: translate3d(0, -100%, 0);
  visibility: hidden;
  pointer-events: none;
  -webkit-transition:
    -webkit-transform 0.36s cubic-bezier(0.4, 0, 0.2, 1),
    visibility 0s linear 0.36s;
  transition:
    transform 0.36s cubic-bezier(0.4, 0, 0.2, 1),
    -webkit-transform 0.36s cubic-bezier(0.4, 0, 0.2, 1),
    visibility 0s linear 0.36s;
  will-change: transform;
}
body.is-menu-open { overflow: hidden; }
.lux-menu.is-open {
  -webkit-transform: translate3d(0, 0, 0);
  transform: translate3d(0, 0, 0);
  visibility: visible;
  pointer-events: auto;
  -webkit-transition:
    -webkit-transform 0.36s cubic-bezier(0.4, 0, 0.2, 1),
    visibility 0s linear 0s;
  transition:
    transform 0.36s cubic-bezier(0.4, 0, 0.2, 1),
    -webkit-transform 0.36s cubic-bezier(0.4, 0, 0.2, 1),
    visibility 0s linear 0s;
}
.lux-menu-inner {
  max-width: var(--container);
  margin: 0 auto;
  padding: 1.4rem var(--container-pad) calc(2rem + env(safe-area-inset-bottom));
}
/* Sections don't have a divider between them — each section's eyebrow is
   the only visual separator. */
.lux-menu-section + .lux-menu-section { margin-top: 1.4rem; }
.lux-menu-eye {
  font-size: 10.5px; letter-spacing: 0.22em; text-transform: uppercase;
  color: var(--stone); font-weight: 500;
  display: block; margin-bottom: 0.15rem;
}
/* When an eyebrow appears mid-level (e.g. the 'Connect' eyebrow in the
   root list), give it some breathing room above — but keep it close to
   the link directly below. Match both the link sibling (legacy) and the
   group sibling (current single-level menu where parents are wrapped in
   .lux-menu-group). */
.lux-menu-link + .lux-menu-eye,
.lux-menu-group + .lux-menu-eye { margin-top: 1.6rem; }
.lux-menu-link {
  display: flex; align-items: center; justify-content: space-between;
  padding: 0.5rem 0;
  font-size: clamp(1.35rem, 4vw, 1.7rem);
  font-weight: 500;
  letter-spacing: -0.02em;
  color: var(--ink);
  text-decoration: none;
  background: none; border: 0;
  text-align: left;
  width: 100%;
  cursor: pointer;
  font-family: inherit;
  transition: color 0.15s ease, padding 0.15s ease;
  /* iOS — kill the grey/blue tap rectangle that flashes over the link
     for ~1s after a tap. */
  -webkit-tap-highlight-color: transparent;
  -webkit-touch-callout: none;
}
/* Hover styles are scoped to (hover: hover) so iOS Safari doesn't keep
   them stuck after a tap (touch devices report hover: none). Without
   this, tapping a parent item left it indented + terracotta even after
   the submenu closed. */
@media (hover: hover) {
  .lux-menu-link:hover { color: var(--acc); padding-left: 4px; }
  .lux-menu-link:hover .lux-menu-link-chev { color: var(--acc); transform: translateX(3px); }
}
/* Right-side chevron for parent items (those that open a sub-level).
   Inline SVG, sized large for prominence but with a thin (1.5px)
   non-scaling stroke so the line weight matches the hamburger bars
   regardless of display size. The viewBox is 24×24 with the chevron
   path drawn with stroke-linecap/linejoin rounded for a soft tip. */
.lux-menu-link-chev {
  flex-shrink: 0;
  width: 1.7rem;
  height: 1.7rem;
  color: var(--stone);
  margin-left: 12px;
  display: inline-block;
  transition: color 0.15s ease, transform 0.15s ease;
}
.lux-menu-link-chev path {
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
}
/* Hide any stray arrow markup left over from earlier markup. */
.lux-menu-link-arrow { display: none; }

/* Single-level menu with inline expandable submenu groups. Tapping a parent
   item reveals its sub-items inline, indented and slightly smaller. The
   parent's row stays put; the items below it slide downward to make room
   while each sub-item fades into view in sequence. */
.lux-menu-list { position: relative; display: block; }

.lux-menu-group { display: block; }

.lux-menu-parent .lux-menu-link-chev { transition: color 0.15s ease, transform 0.25s ease; }
.lux-menu-parent.is-open .lux-menu-link-chev { transform: rotate(90deg); color: var(--acc); }

/* Top-level menu items — opacity-only fade-in for the apple.com cascade.
   Per-item transition-delay is set inline by JS (calc(var(--i)…) in
   CSS isn't reliably honoured on mobile WebKit). Opacity is the
   cheapest property to animate — GPU-composited, no layout impact. */
.lux-menu-list > .lux-menu-link,
.lux-menu-list > .lux-menu-group,
.lux-menu-list > .lux-menu-eye {
  opacity: 0;
  -webkit-transition: opacity 0.22s ease;
  transition: opacity 0.22s ease;
}
.lux-menu.is-open .lux-menu-list > .lux-menu-link,
.lux-menu.is-open .lux-menu-list > .lux-menu-group,
.lux-menu.is-open .lux-menu-list > .lux-menu-eye {
  opacity: 1;
}

/* Submenu drawer — max-height transition is unavoidable here because we
   need the items below the parent button to physically slide down to
   make room. Mobile WebKit can be jerky on max-height, but it's a
   small panel (one open at a time, short content) so the cost is
   bounded. CSS transition (browser-optimised) instead of WAAPI. */
.lux-menu-sub {
  max-height: 0;
  overflow: hidden;
  -webkit-transition: max-height 0.28s cubic-bezier(0.4, 0, 0.2, 1);
  transition: max-height 0.28s cubic-bezier(0.4, 0, 0.2, 1);
}
.lux-menu-sub-inner { display: block; }

.lux-menu-sublink {
  display: block;
  padding: 0.32rem 0 0.32rem 1.4rem;
  font-size: clamp(0.95rem, 2.6vw, 1.1rem);
  font-weight: 400;
  letter-spacing: -0.01em;
  color: var(--ink-mid);
  text-decoration: none;
  font-family: inherit;
  opacity: 0;
  -webkit-tap-highlight-color: transparent;
  -webkit-touch-callout: none;
  -webkit-transition: opacity 0.22s ease, color 0.15s ease, padding 0.15s ease;
  transition: opacity 0.22s ease, color 0.15s ease, padding 0.15s ease;
}
@media (hover: hover) {
  .lux-menu-sublink:hover { color: var(--acc); padding-left: calc(1.4rem + 4px); }
}
.lux-menu-sub.is-open .lux-menu-sublink { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  /* Just the chevron rotation transition — the menu drawer + item
     cascades intentionally keep animating because they're small
     purposeful UI feedback, not vestibular-disturbing motion. */
  .lux-menu-parent .lux-menu-link-chev {
    transition: none !important;
  }
}

/* 18. Nav — transparent frosted glass. The low alpha + heavy backdrop blur
   lets content scroll visibly underneath while keeping the nav text legible. */
.lux-nav {
  position: sticky;
  top: 0;
  z-index: 50;
  height: var(--nav-h);
  background: rgba(245, 243, 238, 0.22);
  -webkit-backdrop-filter: saturate(160%) blur(10px);
          backdrop-filter: saturate(160%) blur(10px);
  border-bottom: 1px solid rgba(45, 40, 36, 0.06);
  display: flex;
  align-items: center;
}
/* Browsers without backdrop-filter support get a slightly more solid bg so
   text stays legible. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .lux-nav { background: rgba(245, 243, 238, 0.85); }
}
.lux-nav-inner { width: 100%; max-width: var(--container); margin: 0 auto; padding: 0 var(--container-pad); display: flex; align-items: center; justify-content: space-between; gap: 1rem; }
.lux-nav-logo { font-weight: 600; font-size: 1rem; letter-spacing: -0.022em; color: var(--ink); text-decoration: none; }
.lux-nav-logo small { font-family: var(--font-mono); font-weight: 400; font-size: 0.62rem; letter-spacing: 0.16em; color: var(--stone); margin-left: 7px; vertical-align: middle; }
.lux-nav-links { display: flex; align-items: center; gap: 1.4rem; }
.lux-nav-link { font-size: 0.82rem; font-weight: 500; color: var(--ink-mid); text-decoration: none; letter-spacing: -0.005em; transition: color 0.15s ease; }
.lux-nav-link:hover { color: var(--acc); }
/* Nav pill — primary CTA. Always orange with bone text so it reads as the
   main action even when the user can't hover (touch). Hover deepens the
   tone but keeps the writing light. */
.lux-nav-link--pill {
  padding: 7px 14px;
  border-radius: 100px;
  background: var(--acc);
  border: 1px solid var(--acc);
  color: var(--bone);
  font-size: 0.78rem;
  letter-spacing: 0.04em;
  transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}
.lux-nav-link--pill:hover { background: var(--acc-deep); border-color: var(--acc-deep); color: var(--bone); }
/* The App pill is a PWA install / open-the-app prompt – only useful on
   touch devices (iOS, iPadOS, Android). On desktop (mouse-precision
   pointer + hover capability) we hide it so it doesn't take up nav space. */
@media (hover: hover) and (pointer: fine) {
  .lux-nav-link--pill { display: none; }
}
/* Settings cog – a label-less icon button that ONLY appears when the
   site is launched as an installed PWA. We hide it everywhere else
   (browser tabs, desktop) because settings only make sense for the
   home-screen experience. */
.lux-nav-cog {
  display: none;
  width: 36px; height: 36px;
  align-items: center; justify-content: center;
  border-radius: 50%;
  color: var(--ink-mid);
  text-decoration: none;
  background: transparent;
  border: 0;
  transition: color 0.15s ease, background 0.15s ease;
}
.lux-nav-cog:hover { color: var(--acc); background: var(--bone-dark); }
.lux-nav-cog svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
@media (display-mode: standalone) {
  .lux-nav-cog { display: inline-flex; }
  /* In a PWA, the App pill is redundant – the user is already in the
     installed app. Hide it so the cog has room to breathe. */
  .lux-nav-link--pill { display: none; }
}
/* iOS Safari uses navigator.standalone instead of display-mode. */
html.lux-pwa .lux-nav-cog { display: inline-flex; }
html.lux-pwa .lux-nav-link--pill { display: none; }
@media (max-width: 560px) {
  .lux-nav-link[data-hide-sm] { display: none; }
  .lux-nav-links { gap: 0.85rem; }
}

/* 19. Crumbs */
.lux-crumbs { display: flex; align-items: center; gap: 0.45rem; flex-wrap: wrap; font-size: 0.78rem; color: var(--stone); margin-bottom: 1.5rem; }
.lux-crumbs a { color: var(--stone); text-decoration: none; }
.lux-crumbs a:hover { color: var(--ink); }
.lux-crumbs-sep { color: var(--rule); }

/* 20. Hero — bone-dark at top fading down to the page canvas, so the hero
   feels distinct without abruptly ending at the next section. Image hero
   overrides via its own bg below. */
.lux-hero {
  padding: var(--hero-py) 0 calc(var(--hero-py) * 0.7);
  background: linear-gradient(180deg, var(--bone-dark) 0%, var(--canvas) 100%);
}
.lux-hero h1 { font-family: var(--font-sans); font-weight: 500; font-size: var(--fz-h1); letter-spacing: -0.02em; line-height: 1.05; margin: 0 0 14px -0.025em; }
/* Description fills the standard column — the container's own padding
   provides the comfortable reading inset. Previously capped at 56ch,
   which sat noticeably short of the 720px narrow column on desktop. */
.lux-hero-sub { font-size: 1rem; color: var(--ink-mid); line-height: 1.6; }

/* Hero with image (home page) — day/night swap */
.lux-hero--image {
  position: relative;
  min-height: 440px;
  display: flex;
  align-items: flex-end;
  background-color: #26201a;
  overflow: hidden;
  padding: var(--hero-py) 0 calc(var(--hero-py) * 0.8);
}
.lux-hero-bg {
  position: absolute;
  inset: 0;
  background-size: cover;
  background-position: center 40%;
  transition: opacity 1.5s ease;
}
.lux-hero-toggle {
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 50px;
  background: transparent;
  border: 0;
  cursor: default;
  z-index: 5;
  padding: 0; margin: 0;
  -webkit-tap-highlight-color: transparent;
}
.lux-hero--image::before {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(to bottom, rgba(38,32,26,0.12) 0%, rgba(38,32,26,0.38) 40%, rgba(38,32,26,0.82) 72%, rgba(38,32,26,0.94) 100%);
  z-index: 1;
  transition: background 1.5s ease;
}
.lux-hero--image.is-night::before {
  background: linear-gradient(to bottom, rgba(0,0,0,0) 0%, rgba(0,0,0,0.27) 40%, rgba(0,0,0,0.7) 72%, rgba(0,0,0,0.7) 100%);
}
.lux-hero--image .lux-container { position: relative; z-index: 2; width: 100%; }
.lux-hero--image h1 { color: #f0ece4; }
.lux-hero--image .lux-eye { color: rgba(240,236,228,0.82); }
.lux-hero--image .lux-hero-sub { color: rgba(240,236,228,0.78); }

/* 21. TOC chips */
.lux-toc { display: flex; flex-wrap: wrap; gap: 0.45rem; margin-top: 1.5rem; }
.lux-toc a {
  font-size: 0.82rem;
  font-weight: 500;
  letter-spacing: -0.005em;
  padding: 9px 16px;
  border-radius: 100px;
  background: rgba(var(--pill-bg-rgb), 0.55);
  -webkit-backdrop-filter: blur(12px) saturate(180%);
          backdrop-filter: blur(12px) saturate(180%);
  border: 1px solid rgba(45, 40, 36, 0.16);
  color: var(--ink);
  text-decoration: none;
  transition: background 0.15s, border-color 0.15s, color 0.15s;
}
.lux-toc a:hover { background: rgba(var(--pill-bg-rgb), 0.85); border-color: var(--acc); color: var(--acc); }

/* 21b. Precinct-in-pocket card — promotes the home-screen PWA. Sits inline
   in the homepage flow. Two-part: dark/image hero on top, neutral card on
   the bottom with a feature list and the Get-the-app CTA.

   Visibility:
   - Mobile browsers: shown (this is who the prompt is for).
   - Installed PWA (display-mode: standalone): hidden, the user already
     has the home-screen app.
   - Desktop (width ≥ 768px): hidden, the prompt only makes sense on
     mobile where you can actually add to the home screen.
   - The .is-pocket-dismissed body class (set by JS when the user taps
     "Not interested" on the top card and stored in localStorage) hides
     #lux-pocket-top across reloads. */
.lux-pocket {
  border-radius: var(--r-md);
  overflow: hidden;
  border: 1px solid var(--rule);
}
@media (display-mode: standalone) {
  .lux-pocket { display: none !important; }
}
@media (min-width: 768px) {
  .lux-pocket { display: none !important; }
}
body.is-pocket-dismissed #lux-pocket-top { display: none !important; }
/* Also hide the wrapper section so the spacing collapses cleanly. */
body.is-pocket-dismissed #lux-pocket-top-wrap { display: none !important; }
.lux-pocket-top {
  position: relative;
  background: #2e2b27 url('https://i.servimg.com/u/f42/20/64/81/21/precin10.png') center/cover;
  padding: 1.5rem 1.4rem 1.6rem;
  isolation: isolate;
}
/* Pulled from the v1 card: a top-down black wash for type contrast,
   layered over a 135° pink → purple → blue colour wash that gives the
   photo its signature 'colourful' feel. */
.lux-pocket-top::before {
  content: '';
  position: absolute; inset: 0;
  z-index: 0;
  background:
    linear-gradient(to bottom, rgba(0, 0, 0, 0.10) 0%, rgba(0, 0, 0, 0.55) 100%),
    linear-gradient(135deg, rgba(236, 72, 153, 0.72) 0%, rgba(147, 51, 234, 0.75) 50%, rgba(59, 130, 246, 0.70) 100%);
}
.lux-pocket-top > * { position: relative; z-index: 1; }
.lux-pocket-eye {
  font-size: 10.5px; letter-spacing: 0.22em; text-transform: uppercase;
  color: rgba(245, 240, 232, 0.85); font-weight: 500;
  margin-bottom: 8px; display: block;
}
/* Headline matches the image-promo title size. The em ('in your pocket.')
   stays inline so the headline reads as one phrase, but never breaks
   mid-phrase — if it can't fit on the same line, the whole em wraps to
   the next line as a unit. */
.lux-pocket-headline {
  font-family: var(--font-sans);
  font-size: var(--promo-h-fz);
  font-weight: 500;
  letter-spacing: -0.025em;
  line-height: 1.04;
  color: var(--bone);
  text-wrap: balance;
}
.lux-pocket-headline .lux-em {
  display: inline;
  white-space: nowrap;
  color: var(--bone);
}
.lux-pocket-sub {
  font-size: 0.9rem; line-height: 1.55;
  color: rgba(245, 240, 232, 0.85);
  margin-top: 12px;
}
@media (min-width: 720px) {
  .lux-pocket-headline { font-size: 1.75rem; }
}
.lux-pocket-bottom {
  background: var(--paper);
  padding: 1.1rem 1.4rem 1.25rem;
}
.lux-pocket-features {
  display: flex; flex-direction: column;
  margin: 0 0 1rem;
  padding: 0;
  list-style: none;
  font-size: 0.85rem; color: var(--ink-mid);
  line-height: 1.6;
}
.lux-pocket-features li { padding: 2px 0; list-style: none; }
.lux-pocket-features li strong { color: var(--ink); font-weight: 600; }
.lux-pocket-channels {
  font-size: 0.78rem; color: var(--stone);
  margin-left: 0.65rem;
}
.lux-pocket-actions {
  display: flex; align-items: center; gap: 1rem;
  flex-wrap: wrap;
}
.lux-pocket-cta {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 8px 16px; border-radius: 999px;
  background: var(--ink); color: var(--bone);
  font-size: 0.82rem; font-weight: 500; letter-spacing: 0.02em;
  text-decoration: none;
  transition: background 0.15s ease;
}
.lux-pocket-cta:hover { background: var(--noir); color: var(--bone); }
.lux-pocket-dismiss {
  font-size: 0.78rem; font-weight: 400;
  color: var(--stone); background: none; border: 0;
  padding: 0; cursor: pointer;
  text-decoration: underline; text-underline-offset: 3px;
  transition: color 0.15s ease;
  font-family: inherit;
}
.lux-pocket-dismiss:hover { color: var(--ink-mid); }

/* ---------- Pocket card: expand in place ----------
   Tapping "Get the app" fades out the simple feature list and
   fades in (a) a compact icon-led feature LIST – no card frames,
   no dividers, just stacked rows – and (b) install steps with
   the iOS/Android switcher. The CTA flips to "Close", which
   plays the same animation in reverse: the expanded items fade
   out and the summary list fades back in. All transitions are
   transition-based (not @keyframes) so reversing is symmetric
   and respects in-flight state. */
.lux-pocket-features[data-pocket-summary] {
  opacity: 1;
  transition: opacity 0.22s ease;
}
.lux-pocket-features[data-pocket-summary].is-fading-out {
  opacity: 0;
  pointer-events: none;
}
.lux-pocket-features[data-pocket-summary].is-fading-in {
  opacity: 0;
}
.lux-pocket.is-expanded .lux-pocket-features[data-pocket-summary] {
  display: none;
}
/* Dismiss button fades in/out alongside the summary – avoids it
   popping in suddenly at the end of the close animation. */
[data-pocket-dismiss] {
  opacity: 1;
  transition: opacity 0.22s ease;
}
.lux-pocket.is-expanded [data-pocket-dismiss],
.lux-pocket.is-collapsing [data-pocket-dismiss] {
  opacity: 0;
  pointer-events: none;
}
.lux-pocket-expanded {
  display: none;
  flex-direction: column;
  gap: 0.9rem;
  margin: 0 0 1rem;
}
.lux-pocket.is-expanded .lux-pocket-expanded {
  display: flex;
}
.lux-pocket-expanded > * {
  opacity: 0;
  transform: translateY(4px);
  transition: opacity 0.22s ease, transform 0.22s ease;
}
/* Top-level children fade up in sequence using their --i. The feats
   container is --i:0 so it appears immediately; the install panel
   is given a higher index in JS so it cascades in AFTER the rolling
   list of items finishes (otherwise it'd appear under them while
   they're still rolling in). */
.lux-pocket.is-expanded:not(.is-collapsing) .lux-pocket-expanded > * {
  opacity: 1;
  transform: translateY(0);
  transition-delay: calc(var(--i, 0) * 60ms);
}
/* Collapsing: every visible expanded child fades out at the same
   time. Duration matches FADE_OUT_MS in theme.js so the height
   shrink (started simultaneously) is perfectly aligned. */
.lux-pocket.is-collapsing .lux-pocket-expanded > * {
  opacity: 0;
  transform: translateY(2px);
  transition-duration: 0.18s;
  transition-delay: 0ms;
}

/* Compact feature list — list items only, no card chrome, no
   horizontal dividers between them. */
.lux-pocket-x-feats {
  display: flex; flex-direction: column;
  gap: 2px;
  padding: 0; margin: 0;
  list-style: none;
}
.lux-pocket-x-feat {
  display: flex; align-items: flex-start; gap: 12px;
  padding: 6px 0;
  background: transparent;
  border: 0;
  /* Stagger fade for individual feature items – each child gets
     its own --i index. The is-collapsing rule above already
     reverses the parent fade; individual rows reverse via this
     rule's symmetry. */
  opacity: 0;
  transform: translateY(3px);
  transition: opacity 0.18s ease, transform 0.18s ease;
}
.lux-pocket.is-expanded:not(.is-collapsing) .lux-pocket-x-feat {
  opacity: 1;
  transform: translateY(0);
  /* 75ms per item gives a clearly perceptible "rolling list" feel
     without dragging the whole entrance out. With six items the
     last one finishes around 75 × 5 + 220 (the fade duration) = 595ms. */
  transition-delay: calc(var(--i, 0) * 75ms);
}
.lux-pocket.is-collapsing .lux-pocket-x-feat {
  opacity: 0;
  transform: translateY(2px);
  transition-duration: 0.18s;
  transition-delay: 0ms;
}
.lux-pocket-x-feat .lux-chip {
  width: 28px; height: 28px; flex: 0 0 28px;
  margin-top: 1px;
}
.lux-pocket-x-feat .lux-chip svg { width: 14px; height: 14px; }
.lux-pocket-x-fbody { min-width: 0; }
.lux-pocket-x-fname {
  display: block;
  font-size: 0.88rem; font-weight: 600;
  color: var(--ink);
  letter-spacing: -0.012em;
  line-height: 1.3;
}
.lux-pocket-x-fdesc {
  display: block;
  font-size: 0.8rem; color: var(--ink-mid);
  line-height: 1.5;
  margin-top: 2px;
}
.lux-pocket-x-installhead {
  display: block;
  font-size: 0.78rem; font-weight: 600;
  color: var(--ink);
  letter-spacing: -0.005em;
  margin: 4px 0 8px;
}
.lux-pocket-x-install .lux-steps { gap: 0.7rem; margin-top: 0.6rem; }
.lux-pocket-x-install .lux-step-num { width: 26px; height: 26px; font-size: 0.74rem; }
.lux-pocket-x-install .lux-step-text { font-size: 0.85rem; line-height: 1.5; }
.lux-pocket-x-install .lux-osswitch { margin-bottom: 0.4rem; }
.lux-pocket-x-install .lux-osswitch button { padding: 5px 14px; font-size: 0.74rem; }
.lux-pocket-x-tip {
  margin-top: 0.7rem;
  font-size: 0.78rem; color: var(--ink-mid);
  line-height: 1.5;
  padding: 0.65rem 0.8rem;
  background: var(--bone-soft);
  border: 1px solid var(--rule);
  border-radius: 8px;
}

/* 21c. Upcoming events list — softly tinted card with day-tag dates. */
.lux-events {
  background: rgba(200, 236, 230, 0.18);
  border: 1px solid rgba(15, 110, 86, 0.18);
  border-radius: var(--r-md);
  overflow: hidden;
}
.lux-events-list { display: flex; flex-direction: column; }
.lux-events-item {
  display: flex; align-items: flex-start; gap: 14px;
  padding: 0.95rem 1.1rem;
  border-bottom: 1px solid rgba(15, 110, 86, 0.12);
}
.lux-events-item:last-child { border-bottom: 0; }
.lux-events-date {
  flex-shrink: 0;
  width: 50px; min-width: 50px;
  text-align: center;
  background: rgba(15, 110, 86, 0.18);
  border-radius: 6px;
  padding: 7px 4px;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  min-height: 56px;
}
.lux-events-date-day { font-size: 1.2rem; font-weight: 600; color: #08503f; line-height: 1; }
.lux-events-date-mon { font-size: 10px; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; color: #0f6e56; margin-top: 4px; }
.lux-events-date-tba { font-size: 1.05rem; font-weight: 600; color: #08503f; line-height: 1; letter-spacing: 0.04em; }
.lux-events-body { flex: 1; min-width: 0; padding-top: 1px; }
.lux-events-title { font-size: 0.92rem; font-weight: 600; color: #08503f; margin-bottom: 4px; letter-spacing: -0.01em; }
.lux-events-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-bottom: 4px; }
.lux-events-pill {
  display: inline-block;
  font-size: 0.72rem; font-weight: 500;
  color: #0f6e56;
  background: rgba(15, 110, 86, 0.14);
  border: 1px solid rgba(15, 110, 86, 0.22);
  border-radius: 4px;
  padding: 2px 7px;
}
.lux-events-time { font-size: 0.8rem; font-weight: 500; color: #0a4840; }
.lux-events-loc { display: flex; align-items: flex-start; gap: 5px; margin-bottom: 4px; }
.lux-events-loc-icon { width: 12px; height: 12px; flex-shrink: 0; fill: none; stroke: #0a4840; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; margin-top: 3px; }
.lux-events-loc-text { font-size: 0.8rem; font-weight: 500; color: #0a4840; }
.lux-events-desc { font-size: 0.8rem; line-height: 1.55; color: #156d63; }
.lux-events-desc-row { padding: 1px 0; }
.lux-events-empty { padding: 1.1rem 1.25rem; font-size: 0.85rem; color: #156d63; text-align: center; }
.lux-events-more {
  display: inline-flex; align-items: center; gap: 6px;
  margin-top: 0.85rem;
  font-size: 0.82rem; font-weight: 500;
  color: var(--ink-mid);
  text-decoration: none;
  letter-spacing: -0.005em;
  transition: color 0.15s ease, padding 0.15s ease;
}
.lux-events-more:hover { color: var(--acc); padding-left: 4px; }
/* Past events get a quieter neutral palette */
.lux-events--past { background: var(--canvas); border-color: var(--rule-faint); }
.lux-events--past .lux-events-item { border-bottom-color: var(--rule-faint); }
.lux-events--past .lux-events-date { background: var(--bone-dark); }
.lux-events--past .lux-events-date-day,
.lux-events--past .lux-events-date-mon,
.lux-events--past .lux-events-date-tba { color: var(--ink-mid); }
.lux-events--past .lux-events-title { color: var(--ink); }
.lux-events--past .lux-events-pill { color: var(--ink-mid); background: var(--bone); border-color: var(--rule); }
.lux-events--past .lux-events-time,
.lux-events--past .lux-events-loc-text,
.lux-events--past .lux-events-loc-icon { color: var(--ink-mid); stroke: var(--ink-mid); }
.lux-events--past .lux-events-desc { color: var(--ink-mid); }

/* 22. Missing / Get-in-touch panel — even more washed than the page bg, with
   a faint border to keep it card-like without being heavy. */
.lux-missing {
  background: rgba(245, 240, 232, 0.4);
  border: 1px solid var(--rule-faint);
  border-radius: var(--r-md);
  padding: 1.6rem 1.75rem;
  text-align: center;
}

/* 22b. App card — chip + name + tag at top, description / note in the
   middle, action pills always pinned to the bottom of the card so adding
   prose never pushes them out of place. */
.lux-app {
  background: var(--paper);
  border: 1px solid var(--rule);
  border-radius: var(--r-md);
  padding: 1.1rem 1.25rem 1.2rem;
  display: flex;
  flex-direction: column;
  gap: 0.7rem;
}
.lux-app-head {
  display: flex; align-items: center; gap: 12px;
  flex-wrap: wrap;
}
.lux-app-head .lux-chip { width: 36px; height: 36px; }
.lux-app-name {
  font-weight: 600; font-size: 1.05rem;
  letter-spacing: -0.018em; color: var(--ink);
  flex: 1; min-width: 0;
  display: inline-flex; align-items: center; gap: 8px; flex-wrap: wrap;
}
.lux-app-btns {
  display: flex; gap: 6px; flex-wrap: wrap;
  justify-content: flex-end;
  margin-top: auto;
  padding-top: 0.4rem;
}
/* Action pill — true rounded pill, used for iOS/Android downloads, the
   COO Q&A "Read" pill, and "Visit X" portal links at the bottom of cards.
   Warm pale-cream tone, ink text. */
.lux-app-btn {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 7px 13px; border-radius: 999px;
  background: rgba(232, 222, 202, 0.55);
  border: 1px solid rgba(160, 140, 95, 0.22);
  color: var(--ink);
  font-size: 0.74rem; font-weight: 500;
  letter-spacing: 0.04em;
  text-decoration: none;
  transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}
.lux-app-btn:hover { background: rgba(232, 222, 202, 0.85); border-color: rgba(160, 140, 95, 0.4); color: var(--acc); }
.lux-app-btn svg { width: 12px; height: 12px; flex-shrink: 0; fill: currentColor; stroke: none; }
.lux-app-btn svg path { fill: currentColor; stroke: none; }
.lux-app-desc { font-size: 0.92rem; color: var(--ink-mid); line-height: 1.6; }
.lux-app-note { font-size: 0.82rem; color: var(--stone); line-height: 1.55; font-style: italic; }
.lux-app-note a { color: var(--acc); text-decoration: underline; text-underline-offset: 2px; }

/* 22c. Feature tiles (homepage-styled, used on /v2/app and elsewhere) */
.lux-feat-grid {
  display: grid; grid-template-columns: 1fr; gap: 8px;
}
@media (min-width: 540px) { .lux-feat-grid { grid-template-columns: 1fr 1fr; gap: 10px; } }
.lux-feat {
  display: flex; align-items: flex-start; gap: 12px;
  padding: 0.85rem 1rem;
  background: var(--paper);
  border: 1px solid var(--rule);
  border-radius: var(--r-md);
}
.lux-feat .lux-chip { width: 34px; height: 34px; }
.lux-feat-body { min-width: 0; }
.lux-feat-name { display: block; font-weight: 600; font-size: 0.96rem; color: var(--ink); letter-spacing: -0.015em; line-height: 1.25; }
.lux-feat-desc { display: block; font-size: 0.83rem; color: var(--ink-mid); line-height: 1.55; margin-top: 3px; }

/* 22d. Step list — palette matches the guide subpages
   (bone-soft circle, rule border, terracotta digit) */
.lux-steps { display: flex; flex-direction: column; gap: 1rem; margin-top: 0.5rem; }
.lux-step { display: flex; align-items: flex-start; gap: 14px; }
.lux-step-num {
  flex: 0 0 auto; width: 32px; height: 32px;
  border-radius: 50%;
  background: var(--bone-soft);
  border: 1px solid var(--rule);
  display: flex; align-items: center; justify-content: center;
  font-size: 0.82rem; font-weight: 600; color: var(--acc);
  margin-top: 1px;
}
.lux-step-text { flex: 1; font-size: 0.92rem; color: var(--ink-mid); line-height: 1.6; }
.lux-step-text strong { color: var(--ink); font-weight: 600; }
.lux-step-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 22px; height: 22px;
  vertical-align: middle;
  color: var(--ink);
}
.lux-step-icon svg { width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }

/* 22e. Segmented OS switcher — animated slider sits behind the active button
   and slides between options. */
.lux-osswitch {
  position: relative;
  display: inline-flex;
  background: var(--bone-soft);
  border: 1px solid var(--rule);
  border-radius: 999px;
  padding: 3px;
  margin-bottom: 1rem;
  isolation: isolate;
}
.lux-osswitch-slider {
  position: absolute; top: 3px; left: 3px;
  height: calc(100% - 6px);
  background: var(--ink);
  border-radius: 999px;
  z-index: 0;
  transform: translate3d(0, 0, 0);
  transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1),
              width 0.25s cubic-bezier(0.4, 0, 0.2, 1);
  pointer-events: none;
  will-change: transform, width;
  -webkit-backface-visibility: hidden;
          backface-visibility: hidden;
}
.lux-osswitch button {
  position: relative; z-index: 1;
  background: transparent; border: 0; cursor: pointer;
  padding: 6px 16px; border-radius: 999px;
  font-size: 0.78rem; font-weight: 500; color: var(--ink-mid);
  font-family: inherit;
  white-space: nowrap;
  transition: color 0.2s ease;
}
.lux-osswitch button.is-active { color: var(--bone); }

/* 22e-bis. Off/On toggle — a two-position variant of the segmented
   OS switcher above. Same animation grammar (sliding dark pill behind
   two buttons). Tuning notes:
     • The slider has NO transition by default. JS adds .is-armed
       after the initial position is laid out, so a toggle that
       starts ON doesn't visibly slide in from the left on page
       load. Subsequent user taps animate normally.
     • The buttons disable text selection and the iOS tap highlight
       so a quick double-tap doesn't paint a blue selection box or
       leave a grey square behind.
     • touch-action: manipulation removes the 300ms tap delay. */
.lux-toggle {
  position: relative;
  display: inline-flex;
  background: var(--bone-soft);
  border: 1px solid var(--rule);
  border-radius: 999px;
  padding: 3px;
  isolation: isolate;
  user-select: none;
  -webkit-user-select: none;
  -webkit-tap-highlight-color: transparent;
}
.lux-toggle-slider {
  position: absolute; top: 3px; left: 3px;
  height: calc(100% - 6px);
  background: var(--ink);
  border-radius: 999px;
  z-index: 0;
  transform: translate3d(0, 0, 0);
  transition: none;
  pointer-events: none;
  will-change: transform, width;
  -webkit-backface-visibility: hidden;
          backface-visibility: hidden;
}
.lux-toggle.is-armed .lux-toggle-slider {
  transition: transform 0.28s cubic-bezier(0.4, 0, 0.2, 1),
              width 0.28s cubic-bezier(0.4, 0, 0.2, 1),
              background 0.22s ease;
}
.lux-toggle.is-on .lux-toggle-slider {
  background: #0BDA51;
}
.lux-toggle button {
  position: relative; z-index: 1;
  background: transparent; border: 0; cursor: pointer;
  padding: 6px 16px; border-radius: 999px;
  font-size: 0.78rem; font-weight: 500; color: var(--ink-mid);
  font-family: inherit;
  white-space: nowrap;
  transition: color 0.2s ease;
  min-width: 48px;
  -webkit-tap-highlight-color: transparent;
  -webkit-user-select: none;
          user-select: none;
  touch-action: manipulation;
  outline: 0;
}
.lux-toggle button:focus { outline: 0; }
.lux-toggle button:focus-visible {
  /* Keyboard-only focus ring – preserves accessibility without
     showing a tap-induced ring on touch. */
  outline: 2px solid var(--acc);
  outline-offset: 2px;
}
.lux-toggle button.is-active { color: var(--bone); }

/* Settings page rows */
.lux-set-list { display: flex; flex-direction: column; gap: 12px; }
.lux-set-row {
  display: flex; align-items: center; justify-content: space-between;
  gap: 14px;
  padding: 1rem 1.1rem;
  background: var(--paper);
  border: 1px solid var(--rule);
  border-radius: var(--r-md);
}
.lux-set-row-body { min-width: 0; flex: 1; }
.lux-set-row-name {
  display: block;
  font-weight: 600; font-size: 0.96rem;
  color: var(--ink); letter-spacing: -0.012em;
  line-height: 1.3;
}
.lux-set-row-desc {
  display: block;
  font-size: 0.82rem; color: var(--ink-mid);
  line-height: 1.5;
  margin-top: 4px;
}
.lux-set-row-note {
  display: block;
  font-size: 0.78rem; color: var(--stone);
  line-height: 1.45;
  margin-top: 6px;
  font-style: italic;
}
.lux-set-row-control { flex: 0 0 auto; }
.lux-set-empty {
  padding: 1.4rem 1.5rem;
  background: var(--bone-soft);
  border: 1px dashed var(--rule);
  border-radius: var(--r-md);
  font-size: 0.88rem; color: var(--ink-mid);
  text-align: center;
}

/* 22f. Info / tip callout — solid card with rounded corners and a left-edge
   accent bar that follows the card's curvature smoothly. The accent uses
   the section colour when scoped inside a tinted section, terracotta otherwise. */
.lux-tip {
  position: relative;
  background: var(--bone-soft);
  border: 1px solid var(--rule);
  border-radius: var(--r-md);
  padding: 0.95rem 1.1rem 0.95rem 1.4rem;
  font-size: 0.9rem; color: var(--ink-mid); line-height: 1.6;
  overflow: hidden;
}
.lux-tip::before {
  content: '';
  position: absolute;
  inset: 0 auto 0 0;
  width: 4px;
  background: var(--section-text, var(--acc));
}
.lux-tip strong { color: var(--ink); font-weight: 600; }
.lux-tip a { color: var(--acc); text-decoration: underline; text-underline-offset: 2px; }
[class*="lux-band--tint-"] .lux-tip {
  background: rgba(255, 255, 255, 0.55);
  border-color: var(--section-rule);
}

/* 23. Footer — dark band, light writing. Same one-line meta on every page. */
.lux-footer {
  margin-top: auto;
  padding: 1.4rem var(--container-pad) calc(1.4rem + env(safe-area-inset-bottom));
  border-top: 0;
  background: var(--noir);
  text-align: center;
  font-size: 0.78rem;
  color: rgba(245, 240, 232, 0.62);
}
.lux-footer-meta { font-size: 0.78rem; line-height: 1.55; color: rgba(245, 240, 232, 0.62); }
.lux-footer-meta a { color: rgba(245, 240, 232, 0.78); text-decoration: none; }
.lux-footer-meta a:hover { color: var(--bone); }
.lux-footer-meta .sep { margin: 0 0.55rem; opacity: 0.45; }

/* 24. Stagger fade-in (residents guide) */
@keyframes lux-fade-in {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: translateY(0); }
}
.lux-fade {
  opacity: 0;
  animation: lux-fade-in 0.5s ease-out forwards;
  animation-delay: var(--d, 0s);
}
@media (prefers-reduced-motion: reduce) { .lux-fade { animation: none; opacity: 1; } }

/* 25. Utility */
.lux-flex { display: flex; }
.lux-flex-wrap { flex-wrap: wrap; }
.lux-items-center { align-items: center; }
.lux-justify-between { justify-content: space-between; }
.lux-gap-1 { gap: 0.5rem; }
.lux-gap-2 { gap: 0.85rem; }
.lux-mt-1 { margin-top: 0.85rem; }
.lux-mt-2 { margin-top: 1.4rem; }
.lux-text-center { text-align: center; }

/* ───────────────────────────────────────────────────────────────────
   26. v2-* compatibility layer — maps the older v2-* class system to
   the same visual language as the lux-* system above so legacy pages
   pick up the new aesthetic without a full HTML rewrite.
   ─────────────────────────────────────────────────────────────────── */

/* Nav */
.v2-nav {
  position: sticky; top: 0; z-index: 100;
  background: rgba(245, 243, 239, 0.85);
  backdrop-filter: blur(14px) saturate(160%);
  -webkit-backdrop-filter: blur(14px) saturate(160%);
  border-bottom: 1px solid var(--rule);
  height: var(--nav-h);
}
.v2-nav-inner {
  max-width: var(--container);
  margin: 0 auto; padding: 0 var(--container-pad);
  height: 100%;
  display: flex; align-items: center; justify-content: space-between;
}
.v2-nav-logo {
  font-family: var(--font-italic); font-style: italic;
  font-size: 1.1rem; font-weight: 400;
  color: var(--ink); text-decoration: none; letter-spacing: -0.01em;
}
.v2-nav-logo small {
  font-family: var(--font-sans); font-style: normal;
  font-size: 9.5px; letter-spacing: 0.22em; text-transform: uppercase;
  color: var(--stone); margin-left: 6px; vertical-align: middle;
}
.v2-nav-links { display: flex; align-items: center; gap: 8px; }
.v2-nav-link {
  font-size: 0.82rem; font-weight: 500;
  color: var(--ink-mid); text-decoration: none;
  padding: 6px 10px; border-radius: 999px;
  transition: color 0.15s ease, background 0.15s ease;
}
.v2-nav-link:hover { color: var(--ink); background: rgba(0, 0, 0, 0.04); }
.v2-nav-pill {
  background: var(--ink); color: var(--bone);
  padding: 7px 14px; font-weight: 500;
}
.v2-nav-pill:hover { background: var(--acc); color: var(--bone); }

/* Container */
.v2-container { max-width: var(--container); margin: 0 auto; padding: 0 var(--container-pad); }
.v2-container--narrow { max-width: var(--container-narrow); }

/* Hero / band */
.v2-hero {
  padding: clamp(2rem, 5vw, 3.5rem) 0 clamp(1.4rem, 3vw, 2rem);
  background: var(--bone);
}
.v2-hero--bone { background: var(--bone); }
.v2-hero-content { max-width: var(--container-narrow); margin: 0 auto; padding: 0 var(--container-pad); }
.v2-hero-sub {
  font-size: 1.05rem; line-height: 1.55;
  color: var(--ink-mid); margin-top: 0.6rem; max-width: 60ch;
}
.v2-band { padding: clamp(2rem, 5vw, 3rem) 0; }
/* Legacy v2-band variants now share the page canvas (matches lux-band). */
.v2-band--bone  { background: transparent; }
.v2-band--paper { background: transparent; }
.v2-band--soft  { background: transparent; }
.v2-band--sm    { padding: clamp(1.4rem, 4vw, 2.2rem) 0; }

/* Eyebrow + headings — matched to .lux-eye / .lux-h2 used on the home page */
.v2-eyebrow {
  display: inline-block;
  font-size: 10.5px; font-weight: 500; letter-spacing: 0.22em;
  text-transform: uppercase; color: var(--stone);
  margin-bottom: 11px;
}
.v2-eyebrow--ondark { color: rgba(245,240,232,0.85); }
.v2-h-md {
  font-family: var(--font-sans); font-weight: 500;
  font-size: var(--fz-h2);
  letter-spacing: -0.02em; line-height: 1.08; color: var(--ink);
  text-wrap: balance;
}
.v2-h-sm {
  font-size: 1.1rem; font-weight: 600;
  letter-spacing: -0.02em; line-height: 1.25; color: var(--ink);
}
.v2-emph { font-family: var(--font-italic); font-style: italic; font-weight: 400; color: var(--acc); font-size: 1.06em; }
.v2-emph--dark { color: var(--ink); }
.v2-prose { font-size: 0.96rem; line-height: 1.65; color: var(--ink-mid); }
.v2-prose p { margin-bottom: 0.85rem; }
.v2-prose p:last-child { margin-bottom: 0; }
.v2-prose strong { color: var(--ink); font-weight: 600; }
.v2-prose a { color: var(--acc); text-decoration: underline; text-underline-offset: 2px; }
.v2-prose-sm { font-size: 0.88rem; line-height: 1.6; color: var(--ink-mid); }

/* Crumbs */
.v2-crumbs {
  display: flex; align-items: center; gap: 6px;
  font-size: 0.78rem; color: var(--stone); margin-bottom: 0.85rem;
}
.v2-crumbs a { color: var(--ink-mid); text-decoration: none; }
.v2-crumbs a:hover { color: var(--acc); }
.v2-crumbs-sep { opacity: 0.5; }

/* Cards */
.v2-card {
  background: var(--paper);
  border: 1px solid var(--rule);
  border-radius: var(--r-md);
  padding: 1.25rem 1.4rem;
}
.v2-card--bone { background: var(--bone-soft); }
.v2-card-eyebrow {
  display: inline-block;
  font-size: 9.5px; font-weight: 500; letter-spacing: 0.22em;
  text-transform: uppercase; color: var(--stone);
  margin-bottom: 4px;
}

/* Buttons */
.v2-btn {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 9px 16px;
  border-radius: 999px;
  font-size: 0.85rem; font-weight: 500;
  text-decoration: none; cursor: pointer;
  border: 1px solid var(--rule);
  background: var(--paper); color: var(--ink);
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease, transform 0.15s ease;
}
.v2-btn:hover { transform: translateY(-1px); }
.v2-btn--accent { background: var(--acc); border-color: var(--acc); color: var(--bone); }
.v2-btn--accent:hover { background: var(--acc-deep); border-color: var(--acc-deep); }
.v2-btn--ink { background: var(--ink); border-color: var(--ink); color: var(--bone); }
.v2-btn--ink:hover { background: #000; }
.v2-btn--ghost { background: transparent; border-color: var(--rule); color: var(--ink); }
.v2-btn--ghost:hover { background: rgba(0,0,0,0.04); }
.v2-btn--small { padding: 6px 12px; font-size: 0.78rem; }

/* Pills */
.v2-pill {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 11px;
  font-size: 0.74rem; font-weight: 500;
  letter-spacing: 0.02em;
  border-radius: 999px;
  background: rgba(var(--pill-bg-rgb), 0.7);
  border: 1px solid rgba(45, 40, 36, 0.14);
  color: var(--ink);
}
.v2-pill--accent { background: var(--acc); color: var(--bone); border-color: var(--acc); }
.v2-pill--blue { background: #d8e3ee; color: #2a3f5b; border-color: #c0cfde; }

/* Grids */
.v2-grid { display: grid; gap: 14px; grid-template-columns: 1fr; }
.v2-grid--2 { grid-template-columns: 1fr; }
@media (min-width: 720px) { .v2-grid--2 { grid-template-columns: 1fr 1fr; } }

/* List rows */
.v2-row {
  display: flex; align-items: center; justify-content: space-between;
  gap: 14px; padding: 1.05rem 0;
  border-bottom: 1px solid var(--rule-faint);
  text-decoration: none; color: inherit;
}
.v2-row:last-child { border-bottom: 0; }
.v2-row-name { font-weight: 600; font-size: 1.02rem; letter-spacing: -0.02em; color: var(--ink); }
.v2-row-desc { font-size: 0.85rem; color: var(--ink-mid); line-height: 1.5; margin-top: 4px; }
.v2-row-arrow { color: var(--stone); flex-shrink: 0; transition: color 0.15s ease, transform 0.15s ease; }
.v2-row:hover .v2-row-arrow { color: var(--acc); transform: translateX(3px); }

/* Accordions */
.v2-acc { border-bottom: 1px solid var(--rule-faint); }
.v2-acc:first-child { border-top: 1px solid var(--rule-faint); }
.v2-acc-head {
  width: 100%;
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; padding: 1rem 0;
  background: transparent; border: 0; cursor: pointer;
  text-align: left; color: var(--ink);
  font-family: inherit;
}
.v2-acc-title { font-weight: 600; font-size: 1rem; letter-spacing: -0.015em; flex: 1; }
.v2-acc-tag {
  font-size: 9.5px; font-weight: 500; letter-spacing: 0.22em;
  text-transform: uppercase; color: var(--acc);
  padding: 3px 9px; border-radius: 999px;
  background: rgba(184, 92, 30, 0.1);
}
.v2-acc-tag--stone { color: var(--stone); background: rgba(0,0,0,0.04); }
.v2-acc-chev { color: var(--stone); flex-shrink: 0; transition: transform 0.2s ease; }
.v2-acc[open] .v2-acc-chev, .v2-acc.is-open .v2-acc-chev { transform: rotate(90deg); color: var(--acc); }
.v2-acc-body { padding: 0 0 1.25rem; color: var(--ink-mid); line-height: 1.65; font-size: 0.94rem; }
.v2-acc-body p { margin-bottom: 0.7rem; }
.v2-acc-body p:last-child { margin-bottom: 0; }
.v2-acc-body a { color: var(--acc); }

/* App cards */
.v2-app-card {
  background: var(--paper);
  border: 1px solid var(--rule);
  border-radius: var(--r-md);
  padding: 1.25rem 1.4rem;
}
.v2-app-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; margin-bottom: 0.5rem; }
.v2-app-name { font-weight: 600; font-size: 1.05rem; letter-spacing: -0.02em; color: var(--ink); }
.v2-app-desc { font-size: 0.9rem; line-height: 1.6; color: var(--ink-mid); margin-bottom: 0.95rem; }
.v2-app-btns { display: flex; gap: 8px; flex-wrap: wrap; }
.v2-app-btn {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 8px 14px; border-radius: 8px;
  background: var(--ink); color: var(--bone);
  font-size: 0.82rem; font-weight: 500;
  text-decoration: none;
}
.v2-app-btn:hover { background: #000; }
.v2-app-note { font-size: 0.8rem; color: var(--stone); margin-top: 0.6rem; }

/* OS switch (segmented control) */
.v2-osswitch {
  display: inline-flex;
  background: var(--bone-soft);
  border: 1px solid var(--rule);
  border-radius: 999px;
  padding: 3px;
  position: relative;
}
.v2-osswitch button {
  background: transparent; border: 0; cursor: pointer;
  padding: 6px 16px; border-radius: 999px;
  font-size: 0.78rem; font-weight: 500; color: var(--ink-mid);
  font-family: inherit;
}
.v2-osswitch button.is-active, .v2-osswitch button[aria-selected="true"] { background: var(--ink); color: var(--bone); }
.v2-osswitch-slider { display: none; }

/* Events */
.v2-event {
  display: flex; gap: 14px;
  padding: 1.1rem 0;
  border-bottom: 1px solid var(--rule-faint);
}
.v2-event:last-child { border-bottom: 0; }
.v2-event-date {
  flex: 0 0 auto; width: 56px; text-align: center;
  padding: 0.5rem 0; border-radius: var(--r);
  background: var(--bone-soft); border: 1px solid var(--rule);
}
.v2-event-day { font-size: 1.4rem; font-weight: 700; letter-spacing: -0.03em; color: var(--ink); line-height: 1; }
.v2-event-mon { font-size: 9.5px; font-weight: 500; letter-spacing: 0.18em; text-transform: uppercase; color: var(--stone); margin-top: 4px; }
.v2-event-body { flex: 1; min-width: 0; }
.v2-event-title { font-weight: 600; font-size: 1.02rem; letter-spacing: -0.02em; color: var(--ink); margin-bottom: 4px; }
.v2-event-desc { font-size: 0.88rem; color: var(--ink-mid); line-height: 1.55; }
.v2-event-desc-row { display: flex; align-items: center; gap: 6px; margin-top: 5px; }
.v2-event-loc { font-size: 0.78rem; color: var(--stone); display: inline-flex; align-items: center; gap: 5px; }
.v2-event-loc-icon { width: 12px; height: 12px; flex-shrink: 0; }
.v2-event-meta { font-size: 0.78rem; color: var(--stone); }
.v2-event-pill {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 9px; font-size: 0.7rem; font-weight: 500;
  letter-spacing: 0.04em; border-radius: 999px;
  background: rgba(184, 92, 30, 0.1); color: var(--acc);
}
.v2-event-tba { color: var(--stone); font-style: italic; }
.v2-event-empty { padding: 2rem 0; text-align: center; color: var(--stone); font-size: 0.92rem; }

/* Promo */
.v2-promo-grid { display: grid; grid-template-columns: 1fr; gap: 12px; }
@media (min-width: 720px) { .v2-promo-grid { grid-template-columns: 1fr 1fr; gap: 14px; } }
.v2-promo {
  display: block;
  position: relative;
  aspect-ratio: 4/5;
  background-size: cover; background-position: center;
  border-radius: var(--r-md); overflow: hidden;
  text-decoration: none; color: var(--bone);
  isolation: isolate;
}
.v2-promo::before {
  content: ""; position: absolute; inset: 0; z-index: 0;
  background: linear-gradient(180deg,
    rgba(0,0,0,0) 0%, rgba(0,0,0,0) 10%,
    rgba(0,0,0,0) 34%,
    rgba(0,0,0,0.56) 66%, rgba(0,0,0,0.78) 100%);
}
.v2-promo-inner {
  position: absolute; left: 18px; right: 18px; bottom: 18px; z-index: 1;
  color: var(--bone);
}
.v2-promo-inner h3 {
  font-family: var(--font-sans); font-weight: 700;
  font-size: 1.5rem; letter-spacing: -0.025em; line-height: 1.1;
  margin: 4px 0 14px;
}
.v2-promo-inner h3 .v2-emph,
.v2-promo-inner h3 .v2-emph--dark { color: var(--bone); }
.v2-promo-cta {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 12px; font-size: 0.78rem; font-weight: 500;
  background: rgba(255,255,255,0.16); backdrop-filter: blur(10px) saturate(160%);
  -webkit-backdrop-filter: blur(10px) saturate(160%);
  border: 1px solid rgba(255,255,255,0.24); border-radius: 999px;
  color: var(--bone);
}

/* Steps */
.v2-steps { display: flex; flex-direction: column; gap: 1rem; }
.v2-step { display: flex; gap: 14px; align-items: flex-start; }
.v2-step-icon, .v2-step-num {
  flex: 0 0 auto; width: 32px; height: 32px;
  border-radius: 50%; background: var(--bone-soft);
  border: 1px solid var(--rule);
  display: flex; align-items: center; justify-content: center;
  font-size: 0.82rem; font-weight: 600; color: var(--acc);
}
.v2-step-text { flex: 1; }
.v2-step-text strong { color: var(--ink); font-weight: 600; }
.v2-step-text p { font-size: 0.92rem; color: var(--ink-mid); line-height: 1.6; margin-top: 3px; }

/* Features */
.v2-feat-list { display: grid; grid-template-columns: 1fr; gap: 14px; margin-top: 1rem; }
@media (min-width: 720px) { .v2-feat-list { grid-template-columns: 1fr 1fr; } }
.v2-feat {
  display: flex; gap: 12px; align-items: flex-start;
  padding: 1rem 1.2rem;
  background: var(--paper);
  border: 1px solid var(--rule); border-radius: var(--r-md);
}
.v2-feat-icon {
  flex: 0 0 auto; width: 36px; height: 36px;
  border-radius: 8px; background: rgba(184, 92, 30, 0.1);
  display: flex; align-items: center; justify-content: center;
  color: var(--acc);
}
.v2-feat-icon svg { width: 18px; height: 18px; }
.v2-feat-name { font-weight: 600; font-size: 0.98rem; letter-spacing: -0.015em; color: var(--ink); }
.v2-feat-desc { font-size: 0.86rem; color: var(--ink-mid); line-height: 1.55; margin-top: 3px; }

/* Detail rows (key-value) */
.v2-detail-row {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 12px; padding: 0.7rem 0;
  border-bottom: 1px solid var(--rule-faint);
}
.v2-detail-row:last-child { border-bottom: 0; }
.v2-detail-label { font-size: 9.5px; font-weight: 500; letter-spacing: 0.22em; text-transform: uppercase; color: var(--stone); flex: 0 0 auto; }
.v2-detail-value { font-size: 0.94rem; color: var(--ink); text-align: right; flex: 1; min-width: 0; }

/* Price list */
.v2-price-list { border-top: 1px solid var(--rule-faint); }
.v2-price-row {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 12px; padding: 0.85rem 0;
  border-bottom: 1px solid var(--rule-faint);
  font-size: 0.94rem; color: var(--ink);
}
.v2-price-row strong { color: var(--ink); font-weight: 600; }

/* Letter / appeal example */
.v2-letter {
  background: var(--paper);
  border: 1px solid var(--rule); border-radius: var(--r-md);
  padding: 1.5rem 1.6rem;
  position: relative;
}
.v2-letter-toolbar {
  display: flex; align-items: center; justify-content: space-between;
  gap: 8px; margin-bottom: 0.85rem;
  padding-bottom: 0.7rem; border-bottom: 1px solid var(--rule-faint);
}
.v2-letter-tlabel {
  font-size: 9.5px; font-weight: 500; letter-spacing: 0.22em;
  text-transform: uppercase; color: var(--stone);
}
.v2-letter-copy {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 11px; font-size: 0.76rem; font-weight: 500;
  background: transparent; border: 1px solid var(--rule); border-radius: 999px;
  color: var(--ink-mid); cursor: pointer;
  font-family: inherit;
}
.v2-letter-copy:hover { background: rgba(184, 92, 30, 0.06); color: var(--acc); border-color: var(--acc); }
.v2-letter-body { font-size: 0.95rem; line-height: 1.7; color: var(--ink); }
.v2-letter-body p { margin-bottom: 0.7rem; }
.v2-letter-body p:last-child { margin-bottom: 0; }
.v2-letter-ph { background: rgba(184, 92, 30, 0.12); padding: 1px 5px; border-radius: 3px; color: var(--acc); font-weight: 500; }

/* TOC */
.v2-toc {
  background: var(--bone-soft);
  border: 1px solid var(--rule);
  border-radius: var(--r-md);
  padding: 1.1rem 1.3rem;
}
.v2-toc ol, .v2-toc ul { list-style: none; counter-reset: toc; }
.v2-toc li { counter-increment: toc; padding: 6px 0; font-size: 0.9rem; }
.v2-toc li::before { content: counter(toc, decimal-leading-zero) "  "; color: var(--stone); font-variant-numeric: tabular-nums; font-size: 0.8rem; }
.v2-toc a { color: var(--ink); text-decoration: none; }
.v2-toc a:hover { color: var(--acc); }

/* Section count */
.v2-section-count {
  font-size: 9.5px; font-weight: 500; letter-spacing: 0.22em;
  text-transform: uppercase; color: var(--stone);
}

/* Tip callout */
.v2-tip {
  background: rgba(184, 92, 30, 0.06);
  border-left: 3px solid var(--acc);
  border-radius: 0 var(--r) var(--r) 0;
  padding: 0.95rem 1.15rem;
  font-size: 0.92rem; line-height: 1.6; color: var(--ink-mid);
}
.v2-tip strong { color: var(--ink); font-weight: 600; }

/* Missing/empty state — match the SAT 'Something missing' card */
.v2-missing {
  background: var(--bone-soft);
  border: 1px solid var(--rule);
  border-radius: var(--r-md);
  padding: 1.6rem 1.75rem;
  text-align: center;
  color: var(--ink);
  font-size: 0.92rem;
}

/* Footer (legacy v2-* layer) — same dark single-line treatment as lux-footer */
.v2-footer {
  border-top: 0;
  padding: 1.4rem var(--container-pad) calc(1.4rem + env(safe-area-inset-bottom));
  margin-top: auto;
  background: var(--noir);
  text-align: center;
  font-size: 0.78rem; color: rgba(245, 240, 232, 0.62);
}
.v2-footer-row { display: none; }
.v2-footer a { color: rgba(245, 240, 232, 0.78); text-decoration: none; }
.v2-footer a:hover { color: var(--bone); }
.v2-footer .sep { margin: 0 0.55rem; opacity: 0.45; }

/* Utility */
.v2-flex { display: flex; }
.v2-flex-wrap { flex-wrap: wrap; }
.v2-items-center { align-items: center; }

/* =================================================================
   VIEW TRANSITIONS — opt into Chromium's cross-document view
   transitions for same-origin nav. Browsers without support ignore
   this rule and just navigate normally. We exclude the banner,
   PTR indicator, and toasts/tooltips from the transition by giving
   them their own view-transition-name so they don't fade in/out
   each navigation. */
@view-transition { navigation: auto; }
.lux-conn-banner   { view-transition-name: lux-banner; }
.lux-ptr           { view-transition-name: lux-ptr; }
.lux-conn-toast    { view-transition-name: lux-toast; }
.lux-share-fab     { view-transition-name: lux-share; }
.lux-progress      { view-transition-name: lux-progress; }

/* =================================================================
   CONNECTION UI — banner, dim states, dot + tooltip, toast, PTR
   -----------------------------------------------------------------
   The whole system uses existing tokens (bone, ink, stone, rule)
   and animates only on transform/opacity so it feels native on
   iOS WebKit.
   ================================================================= */

/* ---------- Banner ----------
   Fixed at viewport top with the iOS safe-area inset baked into a
   single explicit height. Body padding-top and the sticky nav's
   `top` use the same value, so banner and nav butt up cleanly with
   no 1px gap or clip. */
:root {
  --conn-banner-h: 44px;
  --conn-banner-total: calc(var(--conn-banner-h) + env(safe-area-inset-top, 0px));
}
.lux-conn-banner {
  position: fixed; left: 0; right: 0; top: 0;
  z-index: 60;
  box-sizing: border-box;
  height: var(--conn-banner-total);
  padding: env(safe-area-inset-top, 0px) 16px 0;
  display: flex; align-items: center; justify-content: center; gap: 10px;
  font-size: 0.86rem; line-height: 1.25;
  background: var(--bone-dark); color: var(--ink);
  /* No border. The transform-translate above the viewport hides the
     edge entirely when collapsed; no need for a 1px line that can
     misalign with the nav border. */
  transform: translateY(-100%);
  transition: transform 0.34s cubic-bezier(0.4, 0, 0.2, 1), background 0.3s ease, color 0.3s ease;
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
}
.lux-conn-banner.is-visible { transform: translateY(0); }

/* Connecting and back-online states: a washed-out tint of #0BDA51
   with the same dark text colour as the offline banner. The dot is
   the loud signal — it lights up bright green and pulses. */
.lux-conn-banner.is-connecting,
.lux-conn-banner.is-back {
  background: #DCF7E5; /* washed-out #0BDA51 */
  color: var(--ink);
}

.lux-conn-banner-dot {
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--stone);
  flex: 0 0 8px;
}
.lux-conn-banner.is-connecting .lux-conn-banner-dot {
  background: #0BDA51;
  box-shadow: 0 0 10px rgba(11, 218, 81, 0.5);
  animation: lux-conn-pulse 0.55s ease-in-out infinite;
}
.lux-conn-banner.is-back .lux-conn-banner-dot {
  background: #0BDA51;
  box-shadow: 0 0 10px rgba(11, 218, 81, 0.45);
  animation: none;
}
@keyframes lux-conn-pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.25; } }

.lux-conn-banner-ic {
  width: 16px; height: 16px; flex: 0 0 16px;
  stroke: currentColor; fill: none; stroke-width: 2;
  stroke-linecap: round; stroke-linejoin: round;
}

/* When the banner is shown, push body and nav by the same exact
   distance — no clipping, no seam. The nav keeps its frosted-glass
   look (don't override the backdrop-filter) so the banner-to-nav
   transition reads as one continuous panel. */
body.is-conn-banner-shown {
  padding-top: var(--conn-banner-total);
  transition: padding-top 0.34s cubic-bezier(0.4, 0, 0.2, 1);
}
body.is-conn-banner-shown .lux-nav {
  top: var(--conn-banner-total);
  transition: top 0.34s cubic-bezier(0.4, 0, 0.2, 1);
}
/* Megamenu drops down from below the nav. When banner is shown the
   nav has shifted, so the menu's anchor must shift too — otherwise
   the top of the menu sits hidden behind the nav. */
body.is-conn-banner-shown .lux-menu {
  top: calc(var(--conn-banner-total) + var(--nav-h));
  height: calc(100vh - var(--conn-banner-total) - var(--nav-h));
}
@media (max-width: 480px) {
  .lux-conn-banner { font-size: 0.82rem; padding-left: 12px; padding-right: 12px; }
}

/* ---------- Dim state: notification-bubble badge + tap tooltip ----------
   The badge is a small red error glyph (filled circle with a centred
   white "!" SVG) that pokes out of the top-right corner like an iOS
   app notification badge. Two implementation notes:

   1. The "!" is rendered as an inline SVG via background-image rather
      than a text glyph. Text glyphs are not horizontally centred at
      their pixel-box centre (the "!" stem sits a touch left of centre
      in most fonts) and centring tricks like flex/text-align are
      affected by font metrics. The SVG is dead-centre by construction.

   2. We deliberately DON'T apply filter:grayscale to the parent here.
      Filter is inherited by descendants including pseudo-elements,
      which made the badge red look different on channel cards
      (parent grayscale 0.45) vs other items (parent grayscale 0.7).
      Opacity alone is enough visual signal that the link is offline.
*/
:root {
  --err:        #DA1E28;
  --err-deep:   #B91C20;
}

/* The actual glyph is encoded as an SVG data URI: a centred bang
   (vertical line + dot) in white, viewBox 0 0 24 24 so the geometric
   centre is x=12. Stroke-width 3.5 gives it weight at small sizes. */

a.lux-needs-online {
  position: relative;
  opacity: 0.6;
  transition: opacity 0.25s ease;
  -webkit-tap-highlight-color: transparent;
}
a.lux-needs-online::after {
  content: '';
  position: absolute;
  top: -5px; right: -5px;
  width: 16px; height: 16px;
  border-radius: 50%;
  background-color: var(--err);
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3.5' stroke-linecap='round'><line x1='12' y1='6' x2='12' y2='13'/><circle cx='12' cy='17.5' r='1.4' fill='white' stroke='none'/></svg>");
  background-repeat: no-repeat;
  background-position: center;
  background-size: 70% 70%;
  box-shadow: 0 0 0 2px var(--bone), 0 1px 3px rgba(20, 18, 16, 0.28);
  pointer-events: none;
  z-index: 2;
}

/* Channel and promo cards: hide the card-level badge and surface it
   on the inner action pill instead. */
a.lux-channel.lux-needs-online,
a.lux-promo.lux-needs-online {
  opacity: 0.75;
}
a.lux-channel.lux-needs-online::after,
a.lux-promo.lux-needs-online::after {
  display: none;
}
a.lux-channel.lux-needs-online .lux-pill,
a.lux-promo.lux-needs-online .lux-pill {
  position: relative;
}
a.lux-channel.lux-needs-online .lux-pill::after,
a.lux-promo.lux-needs-online .lux-pill::after {
  content: '';
  position: absolute;
  top: -5px; right: -5px;
  width: 16px; height: 16px;
  border-radius: 50%;
  background-color: var(--err);
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3.5' stroke-linecap='round'><line x1='12' y1='6' x2='12' y2='13'/><circle cx='12' cy='17.5' r='1.4' fill='white' stroke='none'/></svg>");
  background-repeat: no-repeat;
  background-position: center;
  background-size: 70% 70%;
  box-shadow: 0 0 0 2px var(--bone), 0 1px 3px rgba(20, 18, 16, 0.28);
  pointer-events: none;
  z-index: 2;
}

/* Newsletter post cards (.lux-news-mag) have overflow:hidden for
   their image animation, which clips a negative-offset badge, AND
   their ::after is already used for the dark gradient overlay. We
   suppress the link-level ::after badge here and put it on ::before
   instead, positioned INSIDE the card so it isn't clipped. */
a.lux-news-mag.lux-needs-online {
  opacity: 0.85;
}
a.lux-news-mag.lux-needs-online::after {
  /* keep the existing gradient — restore by overriding the badge rule */
  content: '';
  background: linear-gradient(180deg,
    rgba(20, 17, 15, 0) 35%,
    rgba(20, 17, 15, 0.55) 75%,
    rgba(20, 17, 15, 0.82) 100%);
  inset: 0;
  top: 0; right: 0;
  width: auto; height: auto;
  border-radius: 0;
  box-shadow: none;
  z-index: 0;
}
a.lux-news-mag.lux-needs-online::before {
  content: '';
  position: absolute;
  top: 12px; right: 12px;
  width: 22px; height: 22px;
  border-radius: 50%;
  background-color: var(--err);
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3' stroke-linecap='round'><line x1='12' y1='6' x2='12' y2='13'/><circle cx='12' cy='17.5' r='1.4' fill='white' stroke='none'/></svg>");
  background-repeat: no-repeat;
  background-position: center;
  background-size: 70% 70%;
  box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.85), 0 2px 6px rgba(20, 18, 16, 0.35);
  pointer-events: none;
  z-index: 3;
}

/* Megamenu drawer links – we replace the corner badge entirely with
   a small dark-grey pill on the right that says "Needs internet".
   Far more legible than a tiny coloured dot in the corner of a long
   row, and matches how iOS / Android list rows convey "unavailable". */
.lux-menu-link.lux-needs-online,
.lux-menu-sublink.lux-needs-online {
  position: relative;
  padding-right: 9.5rem; /* room for the pill on the right */
}
.lux-menu-link.lux-needs-online::after,
.lux-menu-sublink.lux-needs-online::after {
  content: 'Needs internet';
  position: absolute;
  top: 50%;
  right: 14px;
  transform: translateY(-50%);
  padding: 4px 10px;
  border-radius: 999px;
  background: var(--ink-mid);
  color: var(--bone);
  font-family: var(--font-sans), -apple-system, sans-serif;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  line-height: 1.3;
  width: auto; height: auto;
  background-image: none;
  box-shadow: none;
  white-space: nowrap;
  pointer-events: none;
  z-index: 2;
}

/* Non-anchor buttons opting in via [data-needs-online]. */
button.lux-needs-online,
[role="button"].lux-needs-online {
  opacity: 0.55;
  pointer-events: none;
  position: relative;
}

/* ---------- Tap tooltip ----------
   Anchored to the link being tapped. The previous version used
   transform-based positioning (translate(-50%) for centring, plus
   translateY for the gap) which combined with the arrow's own
   transform was a recipe for edge-case bugs. The current version
   uses plain top/left positioning calculated entirely in JS, with
   transform reserved for the scale-in entrance animation only. */
.lux-conn-tooltip {
  position: fixed;
  z-index: 80;
  background: var(--ink); color: var(--bone);
  padding: 7px 11px; border-radius: 8px;
  font-size: 0.8rem; line-height: 1.3; font-weight: 500;
  max-width: 260px;
  pointer-events: none;
  opacity: 0;
  transform: scale(0.96);
  transform-origin: 50% 100%;
  transition: opacity 0.18s ease, transform 0.22s cubic-bezier(0.2, 0.7, 0.3, 1);
  box-shadow: 0 8px 24px rgba(20, 18, 16, 0.22);
}
.lux-conn-tooltip.is-visible {
  opacity: 1;
  transform: scale(1);
}
.lux-conn-tooltip.is-below {
  transform-origin: 50% 0%;
}

/* Arrow: a 12px square rotated 45° with `bottom: -6px` so the top
   half overlaps the tooltip body (same colour, blends seamlessly)
   and the bottom half pokes out as the tip. JS sets --lux-arrow-x
   to the link's centre relative to the tooltip's left edge, so the
   arrow always points at the link even when the body is clamped to
   the viewport. */
.lux-conn-tooltip::after {
  content: '';
  position: absolute;
  left: var(--lux-arrow-x, 50%);
  bottom: -6px;
  width: 12px; height: 12px;
  background: var(--ink);
  transform: translateX(-50%) rotate(45deg);
  border-radius: 2px;
}
/* When the tooltip flips below its anchor, mirror the arrow to the
   top edge so it points UP at the link beneath. */
.lux-conn-tooltip.is-below::after {
  top: -6px;
  bottom: auto;
}

/* ---------- Toasts ----------
   Generic toast component. We use one node per message so multiple
   toasts can stack briefly without fighting each other. */
.lux-conn-toast {
  position: fixed; z-index: 70;
  bottom: calc(20px + env(safe-area-inset-bottom, 0px));
  right: 20px;
  display: flex; align-items: center; gap: 10px;
  padding: 11px 14px;
  background: var(--ink); color: var(--bone);
  border-radius: 10px;
  font-size: 0.86rem; line-height: 1.35;
  box-shadow: 0 6px 24px rgba(20, 18, 16, 0.22);
  opacity: 0; transform: translateY(10px);
  transition: opacity 0.32s ease, transform 0.32s ease;
  pointer-events: none;
  max-width: calc(100vw - 40px);
}
.lux-conn-toast.is-visible { opacity: 1; transform: translateY(0); }
.lux-conn-toast-ic {
  width: 16px; height: 16px; flex: 0 0 16px;
  stroke: currentColor; fill: none; stroke-width: 2;
  stroke-linecap: round; stroke-linejoin: round;
}
@media (max-width: 600px) {
  .lux-conn-toast {
    left: 16px; right: 16px;
    bottom: calc(16px + env(safe-area-inset-bottom, 0px));
    justify-content: center;
  }
}

/* ---------- Pull-to-refresh ----------
   The page itself translates during the pull (body transform). The
   PTR indicator sits on documentElement so it isn't affected by
   the body transform. The indicator is positioned ABOVE where the
   nav and offline banner sit normally (negative top), so as the
   page pulls down it appears in the freshly-revealed white space
   between the viewport edge and the page content — never sitting
   over the nav or banner. The icon parallaxes at ~50% of the page
   rate so it feels grounded under the moving page. */
.lux-ptr {
  position: fixed; left: 0; right: 0;
  /* Sit above the natural top of the page. As body translates down
     by the pull amount, the gap between viewport-top and where the
     page content begins is filled by this indicator. */
  top: calc(env(safe-area-inset-top, 0px) + 14px);
  z-index: 30;
  pointer-events: none;
  display: flex; align-items: flex-start; justify-content: center;
  height: 60px;
  opacity: 0;
}
/* The icon + label sit inside a pill that matches the rest of the
   design system (paper-tone, rounded, soft shadow). Without this
   container the indicator floats on raw white space and looks
   detached from the page – particularly noticeable when the
   offline banner is showing. */
.lux-ptr-inner {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 8px 14px 8px 12px;
  background: var(--paper);
  border: 1px solid var(--rule);
  border-radius: 999px;
  box-shadow: 0 6px 18px rgba(20, 18, 16, 0.10),
              0 1px 2px rgba(20, 18, 16, 0.04);
  color: var(--ink-mid);
  transition: color 0.18s ease, background 0.18s ease, border-color 0.18s ease, box-shadow 0.18s ease;
  will-change: transform, color;
}
.lux-ptr-icon {
  width: 16px; height: 16px;
  stroke: currentColor; fill: none; stroke-width: 2;
  stroke-linecap: round; stroke-linejoin: round;
  flex: 0 0 16px;
}
.lux-ptr-label {
  font-family: 'Mulish', var(--font-sans), system-ui, sans-serif;
  font-size: 0.78rem; font-weight: 500;
  letter-spacing: 0.01em;
  color: inherit;
  white-space: nowrap;
}
/* When the user pulls past the trigger threshold, the pill flips
   to a filled-ink state so it reads "ready to release". The label
   text content is updated by JS in tandem (Pull → Release → Refreshing). */
.lux-ptr.is-ready .lux-ptr-inner {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--bone);
  box-shadow: 0 8px 22px rgba(20, 18, 16, 0.18),
              0 1px 2px rgba(20, 18, 16, 0.06);
}
.lux-ptr.is-refreshing .lux-ptr-icon {
  animation: lux-ptr-spin 0.7s linear infinite;
}
@keyframes lux-ptr-spin { to { transform: rotate(360deg); } }

/* The page itself — body — gets translated during the pull. */
body.is-ptr-pulling { will-change: transform; }
body.is-ptr-snapping {
  transition: transform 0.32s cubic-bezier(0.4, 0, 0.2, 1);
}

/* ---------- Share FAB ----------
   Floating action button on guide / contact / resource pages.
   Terracotta on bone — pulls from the existing accent colour so it
   feels like part of the design system, not an injected control. */
.lux-share-fab {
  position: fixed; z-index: 45;
  right: 18px;
  bottom: calc(18px + env(safe-area-inset-bottom, 0px));
  width: 46px; height: 46px;
  border-radius: 50%;
  background: var(--acc);
  color: var(--paper);
  border: none;
  box-shadow: 0 6px 18px rgba(184, 92, 30, 0.32), 0 2px 6px rgba(20, 18, 16, 0.12);
  display: flex; align-items: center; justify-content: center;
  cursor: pointer;
  transform: translateY(8px); opacity: 0;
  transition: opacity 0.3s ease, transform 0.3s cubic-bezier(0.4, 0, 0.2, 1), background 0.2s ease, box-shadow 0.2s ease;
}
.lux-share-fab.is-visible { opacity: 1; transform: translateY(0); }
.lux-share-fab:hover {
  background: var(--acc-deep);
  box-shadow: 0 8px 22px rgba(184, 92, 30, 0.42), 0 2px 6px rgba(20, 18, 16, 0.14);
}
.lux-share-fab:active { transform: translateY(0) scale(0.94); }
.lux-share-fab svg { width: 18px; height: 18px; stroke: currentColor; fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
/* When PTR is active or banner is shown, FAB stays put. No special
   adjustments needed. */

/* ---------- Reading progress bar ----------
   Thin progress strip under the banner/nav for long guide pages. */
.lux-progress {
  position: fixed; left: 0; right: 0;
  top: var(--nav-h);
  height: 2px;
  background: rgba(184, 92, 30, 0.15); /* terracotta-tinted track */
  z-index: 48;
  pointer-events: none;
}
body.is-conn-banner-shown .lux-progress {
  top: calc(var(--conn-banner-total) + var(--nav-h));
}
.lux-progress-bar {
  height: 100%;
  width: 0%;
  background: var(--acc);
  transition: width 0.08s linear;
  transform-origin: left center;
}

/* ---------- Add to calendar pill ----------
   Tinted with the same green family as the connection banner —
   slightly more saturated so it reads as a foreground action
   rather than an ambient state. */
.lux-events-item { position: relative; }
.lux-events-cal {
  position: absolute;
  top: 12px; right: 12px;
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 0.7rem; font-weight: 500;
  padding: 4px 9px;
  border-radius: 999px;
  background: #D5F2DD;
  color: #0F7B30;
  border: 1px solid rgba(11, 218, 81, 0.28);
  cursor: pointer;
  transition: background 0.18s ease, color 0.18s ease, border-color 0.18s ease;
  -webkit-tap-highlight-color: transparent;
}
.lux-events-cal:hover {
  background: #C2EBCD;
  border-color: rgba(11, 218, 81, 0.45);
  color: #0A5E25;
}
.lux-events-cal svg {
  width: 12px; height: 12px;
  stroke: currentColor; fill: none; stroke-width: 2;
  stroke-linecap: round; stroke-linejoin: round;
}
@media (max-width: 480px) {
  .lux-events-cal { font-size: 0.65rem; padding: 3px 7px; top: 10px; right: 10px; }
}

/* ---------- Shake-report sheet ----------
   Bottom-centred card prompting the user to email an issue report.
   Triggered by a strong shake gesture; auto-dismisses if not
   actioned. The exclamation icon uses a soft red palette so it
   reads as "alert" without being alarming. */
.lux-shake-sheet {
  position: fixed; z-index: 75;
  left: 50%;
  bottom: calc(20px + env(safe-area-inset-bottom, 0px));
  display: flex; align-items: center; gap: 14px;
  background: var(--paper);
  border: 1px solid var(--rule-soft);
  border-radius: 14px;
  padding: 14px 16px;
  box-shadow: 0 10px 30px rgba(20, 18, 16, 0.18);
  max-width: calc(100vw - 28px);
  opacity: 0;
  transform: translate(-50%, 14px);
  transition: opacity 0.3s ease, transform 0.32s cubic-bezier(0.4, 0, 0.2, 1);
}
.lux-shake-sheet.is-visible {
  opacity: 1;
  transform: translate(-50%, 0);
}
.lux-shake-icon {
  width: 36px; height: 36px; flex-shrink: 0;
  border-radius: 50%;
  background: var(--safety-bg-soft, #F5E6E0);
  color: var(--safety-text, #9A2810);
  display: flex; align-items: center; justify-content: center;
}
.lux-shake-icon svg {
  width: 18px; height: 18px;
  stroke: currentColor; fill: none; stroke-width: 2.4;
  stroke-linecap: round; stroke-linejoin: round;
}
.lux-shake-text {
  font-size: 0.95rem; font-weight: 500;
  color: var(--ink);
}
.lux-shake-action {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: 0.78rem; font-weight: 500;
  padding: 7px 14px; border-radius: 999px;
  background: var(--acc); color: var(--paper);
  text-decoration: none;
  transition: background 0.18s ease, transform 0.12s ease;
  white-space: nowrap;
}
.lux-shake-action:hover { background: var(--acc-deep); }
.lux-shake-action:active { transform: scale(0.96); }
.lux-shake-close {
  width: 30px; height: 30px; flex-shrink: 0;
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  cursor: pointer;
  color: var(--ink-mid);
  background: transparent;
  border: none;
  transition: background 0.18s ease, color 0.18s ease;
}
.lux-shake-close:hover { background: var(--bone); color: var(--ink); }
.lux-shake-close svg {
  width: 14px; height: 14px;
  stroke: currentColor; fill: none; stroke-width: 2.2;
  stroke-linecap: round; stroke-linejoin: round;
}
@media (max-width: 420px) {
  .lux-shake-sheet { gap: 10px; padding: 12px 14px; }
  .lux-shake-text { font-size: 0.88rem; }
  .lux-shake-icon { width: 32px; height: 32px; }
}
