/* ============================================================================
   site.css — the one place tokens and shared components live.
   ============================================================================

   Tokens are copied VERBATIM from the Wikinight Design System project
   (24fd5893-c400-4752-a319-fcce42b882a7), files tokens/colors.css,
   tokens/spacing.css and tokens/typography.css, pulled 2026-08-11. Do not edit
   values here — change them in the design system and re-pull. See
   Design/Design system/SYNCED - Design System state (pulled 2026-08-11).md

   Component classes below are faithful CSS ports of the library, which moved to
   Atomic Design on 2026-08-10: components/{atoms,molecules,organisms}/*.jsx.
   (components/core/ no longer exists.) The source component is named above each
   block. Same rule: don't invent values.

   NOT here: page-specific layout (.vhero, .tabbar, .map, the owner editor).
   Those aren't duplicated, so they aren't the problem this file solves.
   ============================================================================ */

/* ===== tokens/colors.css — verbatim ===== */
:root{
  --color-deep-night:#171717;
  --color-polar-white:#ffffff;
  --color-quiet-fog:#9a9a9a;
  --color-body-white:#e6e6e6;
  --color-night-2:#1f1f1f;
  --color-night-3:#262626;
  --color-night-4:#2e2e2e;
  --color-signal-red:#e03131;
  --color-signal-red-dim:#8f2727;
  --color-fog-dim:#6b6b6b;
  --color-fog-line:#3a3a3a;
  --color-fog-line-hover:#5a5a5a;
  --surface-page:var(--color-deep-night);
  --surface-card:var(--color-night-2);
  --surface-hover:var(--color-night-3);
  --surface-pressed:var(--color-night-4);
  --text-primary:var(--color-polar-white);
  --text-body:var(--color-body-white);
  --text-secondary:var(--color-quiet-fog);
  --text-tertiary:var(--color-fog-dim);
  --text-inverse:var(--color-deep-night);
  --border-hairline:var(--color-fog-line);
  --border-hairline-hover:var(--color-fog-line-hover);
  --border-strong:var(--color-polar-white);
  --border-muted:var(--color-quiet-fog);
  --accent:var(--color-signal-red);
  --border-accent:var(--color-signal-red);
  --text-accent:var(--color-signal-red);
  --status-fresh:var(--color-polar-white);
  --status-aging:var(--color-quiet-fog);
  --status-stale:var(--color-fog-dim);
  --overlay-scrim:rgba(23,23,23,0.72);
  --overlay-glass:rgba(23,23,23,0.55);
}

/* ===== tokens/spacing.css — verbatim ===== */
:root{
  --spacing-unit:4px;
  --space-4:4px;--space-8:8px;--space-12:12px;--space-16:16px;--space-20:20px;
  --space-24:24px;--space-32:32px;--space-40:40px;--space-48:48px;--space-64:64px;
  --space-80:80px;--space-120:120px;
  --page-max-width:1200px;
  --section-gap:96px;
  --card-padding:24px;
  --element-gap:12px;
  --radius-sm:4px;--radius-md:8px;--radius-lg:12px;--radius-xl:16px;
  --radius-2xl:24px;--radius-pill:999px;
  --border-width-hairline:1px;
  --border-width-active:2px;
  --shadow-card:0 1px 1px rgba(0,0,0,0.2),0 4px 5px rgba(0,0,0,0.15);
  --shadow-nav:0 2px 6px rgba(0,0,0,0.3);
  /* Stacking order — the whole ladder. NEVER pick a z-index locally: a value that
     works inside one component loses to page chrome on a real page. Ascending, and
     the order IS the rule — page chrome, then the bar that commits, then anything
     that OPENS on top of them, then the one thing that must never be hidden. */
  --z-sticky:40;      /* SectionTabs, a page's own nav wrapper */
  --z-commit-bar:50;  /* StickyActionBar */
  --z-popover:60;     /* Select / MultiSelect menus, OpenState week, SearchField panel */
  --z-toast:80;       /* Toast — above everything, always */
  --blur-nav:blur(14px);
  --ease-out:cubic-bezier(0.22,1,0.36,1);
  --duration-fast:120ms;--duration-base:200ms;--duration-slow:350ms;
}

/* ===== tokens/typography.css — verbatim =====
   The scale used to be omitted here: typography.css defined --text-body as 17px
   while colors.css defines it as the colour #e6e6e6, so importing both made every
   `color:var(--text-body)` resolve to a length. The rename requested as request 2
   LANDED (pulled 2026-08-11) — sizes are now --text-*-size and the collision is
   gone, so the scale is copied down for the first time. The bare --text-* names
   remain COLOURS; never reuse one for the other. */
:root{
  --font-display:'Clash Display','ClashDisplay-Variable',ui-sans-serif,system-ui,sans-serif;
  --font-ui:'General Sans','GeneralSans-Variable',ui-sans-serif,system-ui,-apple-system,'Segoe UI',sans-serif;
  --weight-display:400;
  --weight-display-small:500;
  --weight-body:400;
  --weight-ui:500;
  --weight-strong:600;   /* rare — numerals, key data only */
  --text-display-size:46px;   --leading-display:1.1;    --tracking-display:-0.01em;
  --text-heading-size:27px;   --leading-heading:1.2;    --tracking-heading:-0.008em;
  --text-subheading-size:24px;--leading-subheading:1.3; --tracking-subheading:-0.007em;
  --text-body-size:17px;      --leading-body:1.5;       --tracking-body:-0.005em;
  --text-ui-size:14px;        --leading-ui:1.3;         --tracking-ui:-0.003em;
  --text-caption-size:12px;   --leading-caption:1.4;    --tracking-caption:0;
  --text-micro-size:10px;     --leading-micro:1.3;      --tracking-micro:0.06em;
}

/* ===== tokens/fonts.css — self-hosted, no network =====
   Both faces are Fontshare variable fonts, so one file covers every weight the
   system asks for (400 display, 400 body, 500 UI, 700 numerals).

   Clash Display is the file `assets/brand/brand.css` already ships — same path,
   same family name, so the two declarations agree and either file can load
   first. `local()` comes first so a machine with the font installed skips the
   download. Licences ship beside the files (Fontshare FFL, both faces). */
@font-face{
  font-family:'Clash Display';
  src:local('Clash Display'),url('brand/fonts/ClashDisplay-Variable.woff2') format('woff2-variations');
  font-weight:200 700; font-style:normal; font-display:swap;
}
@font-face{
  font-family:'General Sans';
  src:local('General Sans'),url('fonts/GeneralSans-Variable.woff2') format('woff2-variations');
  font-weight:200 700; font-style:normal; font-display:swap;
}
@font-face{
  font-family:'General Sans';
  src:local('General Sans Italic'),url('fonts/GeneralSans-VariableItalic.woff2') format('woff2-variations');
  font-weight:200 700; font-style:italic; font-display:swap;
}

/* Two page measures. 1200px is the design system's --page-max-width and belongs
   to grid pages (home, search). 920px is a reading measure for a single venue
   (detail, owner) — a deliberate narrowing, not drift. */
:root{
  --page-measure:920px;
}

/* ===== Reset ===== */
*{box-sizing:border-box;}
html{scroll-behavior:smooth;}
body{
  margin:0; background:var(--surface-page); color:var(--text-primary);
  font-family:var(--font-ui); font-weight:var(--weight-body);
  -webkit-font-smoothing:antialiased; letter-spacing:-0.005em; line-height:1.5;
}
/* The design system's base.css underlines every <a> with a muted bottom border.
   That's right for prose links and wrong for nav, cards and chips, which is
   nearly every link here — so links are bare by default and the pages add an
   underline where a link is genuinely inline in text. */
a{color:inherit; text-decoration:none;}
img{max-width:100%; display:block;}
[hidden]{display:none !important;}
:focus-visible{outline:2px solid var(--border-strong); outline-offset:2px;}
::selection{background:var(--color-polar-white); color:var(--color-deep-night);}

.wrap{max-width:var(--page-max-width); margin:0 auto; padding:0 var(--space-24);}
/* Reading pages opt into the narrower measure by setting --page-measure locally. */
.wrap--measure{max-width:var(--page-measure);}

/* §4.3 micro meta-label recipe */
.micro{
  font-size:10px; font-weight:var(--weight-ui); letter-spacing:0.06em;
  text-transform:uppercase; color:var(--text-secondary); margin:0;
}

/* ===== Icon — components/core/Icon.jsx =====
   A wrapper span that CONTAINS the svg. Never a class on the svg itself: the
   component sets its own box and lets stroke inherit currentColor, and the two
   are not interchangeable. Contexts override the 18px default. */
.ic{
  display:inline-flex; align-items:center; justify-content:center;
  width:18px; height:18px; flex-shrink:0; vertical-align:middle;
}
.ic svg{width:100%; height:100%;}

/* ===== Button — components/core/Button.jsx ===== */
.btn{
  display:inline-flex; align-items:center; justify-content:flex-start; gap:10px; flex-shrink:0;
  font-family:var(--font-ui); font-weight:var(--weight-ui); font-size:14px;
  letter-spacing:-0.003em; line-height:1.3; white-space:nowrap;
  border-radius:var(--radius-md); padding:10px 18px; background:transparent; cursor:pointer;
  transition:background var(--duration-base) var(--ease-out),
             border-color var(--duration-base), color var(--duration-base);
}
.btn:disabled{opacity:.4; cursor:default;}
.btn .ic{width:16px; height:16px;}
.btn--outlined{border:1px solid var(--border-strong); color:var(--text-primary);}
.btn--accent{border:1px solid var(--border-accent); color:var(--text-accent);}
.btn--secondary{border:1px solid var(--border-muted); color:var(--text-secondary);}
.btn--filled{border:1px solid var(--color-polar-white); background:var(--color-polar-white); color:var(--text-inverse);}
.btn--ghost{border:1px solid transparent; color:var(--text-secondary); padding:10px 6px;}
.btn--dashed{border:1px dashed var(--border-muted); color:var(--text-secondary); width:100%; justify-content:center;}
.btn--filled:hover{background:#e8e8e8; border-color:#e8e8e8;}
.btn--accent:hover{background:var(--surface-hover);}
.btn--outlined:hover,.btn--secondary:hover{background:var(--surface-hover); color:var(--text-primary); border-color:var(--border-strong);}
.btn--ghost:hover{background:var(--surface-hover); color:var(--text-primary);}
.btn--dashed:hover{border-color:var(--border-strong); color:var(--text-primary);}

/* ===== Chip — components/core/Chip.jsx =====
   Transparent at rest, hover one night step, selected = pressed wash + white
   border + white text. The selected state is the component's, not an invention:
   owner.html has no filters so it never needed one. */
.chip{
  display:inline-flex; align-items:center; gap:var(--space-8); background:transparent;
  border:1px solid var(--border-hairline); border-radius:var(--radius-pill); padding:8px 16px;
  color:var(--text-secondary); font-family:var(--font-ui); font-size:13px;
  font-weight:var(--weight-ui); white-space:nowrap;
  transition:background var(--duration-base) var(--ease-out),
             border-color var(--duration-base) var(--ease-out),
             color var(--duration-base) var(--ease-out);
}
.chip .ic{width:15px; height:15px;}
.chip__count{color:var(--text-tertiary); font-weight:var(--weight-body);}
a.chip,button.chip{cursor:pointer;}
a.chip:hover,button.chip:hover{background:var(--surface-hover); color:var(--text-primary);}
.chip.is-selected{background:var(--surface-pressed); border-color:var(--border-strong); color:var(--text-primary);}
.chip.is-selected .chip__count{color:var(--text-secondary);}
/* A read-only tag on a card that happens to match the active filter. */
.chip.is-lit{color:var(--text-primary); border-color:var(--border-strong);}
.chip.is-more{color:var(--text-tertiary);}

/* ===== Input / DateField — components/core/Input.jsx, DateField.jsx =====
   Flat: card fill, radius 0, bottom border only. Focus thickens the underline to
   2px white; error to 2px Signal Red. Padding compensates so nothing shifts. */
.field{display:flex; flex-direction:column; gap:var(--space-8); min-width:0;}
.field__label{
  font-size:10px; font-weight:var(--weight-ui); letter-spacing:0.06em;
  text-transform:uppercase; color:var(--text-secondary);
}
.field__box{
  display:flex; align-items:center; gap:10px; background:var(--surface-card);
  border-bottom:1px solid var(--border-muted); border-radius:0; padding:12px 14px;
  transition:border-color var(--duration-base) var(--ease-out);
}
.field__box:focus-within{border-bottom:2px solid var(--border-strong); padding-bottom:11px;}
.field__box input{
  flex:1; min-width:0; background:transparent; border:none; outline:none; padding:0;
  color:var(--text-primary); font-family:var(--font-ui); font-size:14px; letter-spacing:-0.003em;
}
.field__box input::placeholder{color:var(--text-tertiary);}
.field__box input[type=date]{color-scheme:dark;}
.field__box .lead{display:inline-flex; color:var(--text-tertiary); flex-shrink:0;}
.field__box .lead .ic{width:16px; height:16px;}
.field__msg{font-size:12px; line-height:1.4; color:var(--text-tertiary);}
.field__msg:empty{display:none;}
.field.is-error .field__label{color:var(--text-accent);}
.field.is-error .field__box{border-bottom:2px solid var(--border-accent); padding-bottom:11px;}
.field.is-error .field__msg{color:var(--text-accent);}

/* ===== Textarea — components/core/Textarea.jsx ===== */
.ta{
  width:100%; background:var(--surface-card); border:1px solid var(--border-muted); border-radius:0;
  padding:12px 14px; color:var(--text-primary); font-family:var(--font-ui); font-size:14px;
  line-height:1.5; letter-spacing:-0.003em; outline:none; resize:vertical;
  transition:border-color var(--duration-base) var(--ease-out);
}
.ta::placeholder{color:var(--text-tertiary);}
.ta:focus{border:2px solid var(--border-strong); padding:11px 13px;}
.field.is-error .ta{border:2px solid var(--border-accent); padding:11px 13px;}

/* ===== PriceRow — components/core/PriceRow.jsx =====
   align-items is baseline, per the component. The owner page overrode this to
   flex-start; the component is the authority. */
.pricerow{
  display:flex; align-items:baseline; justify-content:space-between; gap:var(--space-16);
  max-width:560px; padding:11px 12px; margin:0 -12px; border-radius:var(--radius-md);
  background:transparent; transition:background var(--duration-base) var(--ease-out);
}
.pricerow:hover{background:var(--surface-card);}
.pricerow__main{min-width:0; flex:1;}
.pricerow__name{font-size:16px; line-height:1.35; color:var(--text-primary);}
.pricerow__detail{font-size:13px; color:var(--text-secondary); margin-top:2px;}
.pricerow__price{font-size:16px; font-weight:var(--weight-strong); color:var(--text-primary); white-space:nowrap;}

/* ===== EventRow — components/core/EventRow.jsx ===== */
.eventrow{
  background:var(--surface-card); border:1px solid var(--border-hairline);
  border-radius:var(--radius-lg); margin-bottom:var(--space-12);
  transition:border-color var(--duration-base) var(--ease-out);
}
.eventrow__grid{display:grid; grid-template-columns:104px 1fr;}
.eventrow__date{padding:22px 0 22px 22px;}
.eventrow__dow{font-size:10px; text-transform:uppercase; letter-spacing:0.08em; color:var(--text-secondary); display:block;}
.eventrow__day{font-size:28px; font-weight:var(--weight-strong); line-height:1.05; color:var(--text-primary); margin:2px 0; display:block;}
.eventrow__mon{font-size:11px; text-transform:uppercase; color:var(--text-secondary); display:block;}
.eventrow__body{padding:22px 24px;}
.eventrow__title{display:flex; align-items:center; gap:10px;}
.eventrow__title .ic{color:var(--text-secondary);}
.eventrow__title b{
  font-family:var(--font-display); font-weight:var(--weight-body); font-size:21px;
  color:var(--text-primary); flex:0 1 auto; min-width:0; white-space:nowrap;
}
.eventrow__grow{flex:1 1 auto;}
.eventrow__time{font-size:14px; color:var(--text-body); margin-top:var(--space-8);}
.eventrow__desc{font-size:14px; line-height:1.55; color:var(--text-secondary); margin-top:6px;}
.eventrow__tags{display:flex; gap:var(--space-8); flex-wrap:wrap; margin-top:14px; align-items:center;}
.eventrow__cta{
  display:inline-flex; align-items:center; gap:7px; font-size:13px; font-weight:var(--weight-ui);
  color:var(--text-primary); margin-top:14px; transition:gap var(--duration-base) var(--ease-out);
}
.eventrow__cta .ic{width:15px; height:15px;}
.eventrow__cta:hover{gap:11px;}
.eventrow.is-ended{opacity:.62;}
.eventrow.is-active{border-color:var(--border-hairline-hover);}

/* The optional media column. The design system's EventRow supports `image`; the
   owner editor has no field for it, so these are populated during review.

   overflow is clipped only when there IS an image — the media column has square
   corners and would otherwise bleed past the card's radius. Rows without an image
   must stay overflow:visible so the owner editor's select menus can escape them. */
.eventrow.has-img{overflow:hidden;}
.eventrow.has-img .eventrow__grid{grid-template-columns:104px 1fr 240px;}
.eventrow__media{position:relative; background:var(--surface-hover); overflow:hidden;}
.eventrow__media img{position:absolute; inset:0; width:100%; height:100%; object-fit:cover;}

@media (max-width:760px){
  .eventrow.has-img .eventrow__grid{grid-template-columns:104px 1fr;}
  .eventrow.has-img .eventrow__media{grid-column:1 / -1; grid-row:1; aspect-ratio:16/9;}
  .eventrow.has-img .eventrow__date{grid-row:2;}
  .eventrow.has-img .eventrow__body{grid-row:2;}
}
/* Under 600px the date collapses to one inline baseline row, per the component. */
@media (max-width:599px){
  .eventrow__grid,.eventrow.has-img .eventrow__grid{grid-template-columns:1fr;}
  .eventrow.has-img .eventrow__media{grid-column:1; grid-row:1; aspect-ratio:16/9;}
  .eventrow.has-img .eventrow__date,.eventrow.has-img .eventrow__body{grid-row:auto;}
  .eventrow__date{display:flex; align-items:baseline; gap:var(--space-8); padding:18px 22px 0; flex-wrap:wrap;}
  .eventrow__day{font-size:17px; line-height:1; margin:0; order:-1;}
  .eventrow__body{padding:var(--space-8) 22px 20px;}
}

/* ===== SectionTabs — components/core/SectionTabs.jsx ===== */
.sectiontabs{
  /* 57px, not 56: the topbar is 56px plus its 1px hairline. At 56 the two boxes
     overlapped by exactly 1px, and since both sit on --z-sticky the tie was
     settled by DOM order — the translucent tab rail painted over the topbar's
     bottom border. The old 50-vs-40 literals hid this; the ladder exposed it.
     Matching the real height removes the overlap instead of re-fighting it. */
  position:sticky; top:57px; z-index:var(--z-sticky); background:var(--overlay-glass);
  backdrop-filter:var(--blur-nav); -webkit-backdrop-filter:var(--blur-nav);
  border-bottom:1px solid var(--border-hairline);
}
.sectiontabs__inner{
  max-width:var(--page-max-width); margin:0 auto; display:flex; gap:var(--space-24);
  overflow-x:auto; scrollbar-width:none; padding:0 var(--space-24);
}
.sectiontabs--measure .sectiontabs__inner{max-width:var(--page-measure);}
.sectiontabs__inner::-webkit-scrollbar{display:none;}
.stab{
  display:inline-flex; align-items:center; gap:var(--space-8); background:transparent; border:none;
  border-bottom:2px solid transparent; padding:16px 10px; color:var(--text-secondary);
  font-family:var(--font-ui); font-size:15px; font-weight:var(--weight-ui);
  white-space:nowrap; cursor:pointer;
  transition:color var(--duration-base) var(--ease-out), border-color var(--duration-base) var(--ease-out);
}
.stab .ic{width:16px; height:16px; color:var(--text-tertiary);}
.stab:hover{color:var(--text-primary);}
.stab.is-active{color:var(--text-primary); border-bottom-color:var(--border-strong);}
.stab.is-active .ic{color:var(--text-primary);}
.stab__count{font-size:13px; color:var(--text-tertiary); font-weight:var(--weight-body);}

/* ===== Toast — components/core/Toast.jsx ===== */
.toast{
  position:fixed; left:0; right:0; bottom:28px; display:flex; justify-content:center; z-index:var(--z-toast);
  pointer-events:none; opacity:0; transition:opacity var(--duration-base) var(--ease-out);
}
.toast.is-on{opacity:1;}
.toast__pill{
  display:inline-flex; align-items:center; gap:10px; background:var(--surface-card);
  border:1px solid var(--border-hairline); border-radius:var(--radius-pill);
  padding:11px var(--space-20); font-size:14px; color:var(--text-primary);
}
.toast__pill .ic{width:16px; height:16px; color:var(--text-secondary);}

/* ===== Trust line =====
   The verification dot + one sentence, wherever a confirmation is stated. Wording
   comes from trustLine() in format.js; the dot colour is the freshness axis and is
   never Signal Red (design system §3.5).

   NOTE: the unconfirmed variant below is a placeholder pending a design system
   VerifiedBadge state — see Claude Design request 1. It is styled only from
   existing tokens so it can be swapped out cleanly. */
.trust{display:flex; align-items:center; gap:9px; font-size:13px; color:var(--text-secondary); line-height:1.4; margin:0;}
.trust b{font-weight:var(--weight-strong); color:var(--text-primary);}
.trust__dot{width:8px; height:8px; border-radius:var(--radius-pill); background:var(--status-fresh); flex:none;}
.trust--aging .trust__dot{background:var(--status-aging);}
.trust--stale .trust__dot{background:var(--status-stale);}
/* Community-only confirmation reads as a hollow dot. */
.trust--community .trust__dot{background:transparent; box-shadow:inset 0 0 0 1.5px var(--text-secondary);}
.trust--unconfirmed{color:var(--text-tertiary);}
.trust--unconfirmed .trust__dot{background:transparent; box-shadow:inset 0 0 0 1.5px var(--text-tertiary);}

/* The design system's VerifiedBadge (a pill with the dot + "VERIFIED JUL 29") is
   deliberately NOT ported here yet. Adopting it belongs with ListingCard, which
   the public cards will converge on once it gains the address line and tag row
   they need — see Claude Design request 6. One trust element at a time; two would
   put us back where we started. */

/* ===== Listing card =====
   PENDING: hand-rolled, NOT ported from the design system. ListingCard exists
   there in three sizes but carries neither an address line nor a tag row, and
   the public pages need both — requested as ListingCard variants (Claude Design
   request 6). It lives here rather than in two page style blocks so that when
   the real component lands there is exactly one place to swap.

   index.html and search.html render this from the same venueCard() in
   venues.js. Page-owned: the grid that lays the cards out, and search.html's
   `.is-active`, which is map selection and means nothing on the homepage. */
.listing{
  display:block; background:var(--surface-card); border:1px solid var(--border-hairline);
  border-radius:var(--radius-lg); overflow:hidden;
  transition:border-color var(--duration-base) var(--ease-out);
}
.listing:hover{border-color:var(--border-hairline-hover);}
/* Image is context, not the headline — the deal is why people are here. The
   filter keeps photography inside the night palette. */
.listing__img{aspect-ratio:21/9; width:100%; object-fit:cover; filter:saturate(0.85) brightness(0.9);}
.listing__body{padding:var(--space-16) var(--space-20) 18px;}
.listing__hood{color:var(--text-tertiary); margin:0 0 5px;}
.listing__name{font-family:var(--font-display); font-weight:var(--weight-body); font-size:21px; line-height:1.2; letter-spacing:-0.007em; margin:0 0 7px;}
.listing__addr{display:flex; align-items:center; gap:6px; font-size:13px; color:var(--text-secondary); margin:0 0 14px;}
.listing__addr .ic{width:14px; height:14px; color:var(--text-tertiary);}
/* Optional line, shown where the price is the pitch rather than the filter. */
.listing__deal{font-size:15px; color:var(--text-body); margin:0 0 14px;}
.listing__deal b{font-weight:var(--weight-strong);}
/* What's on here — one row, same vocabulary as the filter chips above the grid. */
.pills{display:flex; gap:7px; overflow:hidden; margin:0 0 15px;}
/* A card tag is a Chip at rest, one step smaller to sit inside a card. */
.pills .chip{flex:none; font-size:12px; padding:6px 11px; line-height:1;}

/* ===== Shared page furniture ===== */
.topbar{
  position:sticky; top:0; z-index:var(--z-sticky); background:var(--overlay-topbar);
  backdrop-filter:var(--blur-nav); -webkit-backdrop-filter:var(--blur-nav);
  border-bottom:1px solid var(--border-hairline);
}
.topbar__inner{display:flex; align-items:center; height:56px; padding:0 var(--space-24); max-width:var(--page-max-width); margin:0 auto;}
.topbar--measure .topbar__inner{max-width:var(--page-measure);}
.brand{font-family:var(--font-display); font-weight:var(--weight-display); font-size:21px; letter-spacing:-0.01em;}
/* NOT a design-system port. The DS rule "brand mark = the word Wikinight in
   Playfair Light, no drawn logo exists, do not invent one" is void — one was
   drawn. See "StillOn - Brand Identity v1.md" §7.4 and §8. The type styles above
   stay for any surface still setting the name as text; where a page uses the
   drawn wordmark, it goes inside .brand as an <img> and these two rules size it.

   Sized by height, not width: the lockup is 3.2 track-heights wide, so height is
   the one dial — the same rule the toggle and the film's --h follow. 22px lands
   the mark at the cap height of the 21px Playfair it replaces. */
.brand img{display:block; height:22px; width:auto;}
.foot .brand img{height:26px;}

/* One value for the solid-ish sticky topbar, distinct from --overlay-glass (.55)
   which is for panels floating over imagery. Three different alphas were in use
   before (.82 / .85 / .9). */
:root{--overlay-topbar:rgba(23,23,23,0.85);}

footer{border-top:1px solid var(--border-hairline); padding:var(--space-32) 0 44px;}
.foot{display:flex; justify-content:space-between; align-items:center; gap:var(--space-16); flex-wrap:wrap;}
.foot .brand{font-size:22px;}
.foot a{display:inline-flex; align-items:center; gap:7px; font-size:14px; color:var(--text-secondary); transition:color var(--duration-base) var(--ease-out);}
.foot a .ic{width:16px; height:16px;}
.foot a:hover{color:var(--text-primary);}

@media (max-width:599px){
  .wrap{padding:0 18px;}
  .topbar__inner{padding:0 18px;}
  .sectiontabs__inner{padding:0 18px; gap:var(--space-16);}
}
