/* ============================================================
   ESN Gent Events — styles (1.47, consolidated)
   One sheet in one order: tokens, base, typography, shell, components,
   pages, utilities, keyframes. Every selector is declared once with its
   final value; the version tags next to rules are the history of why.
   ESN palette used as accents on calm, neutral surfaces:
   Cyan #00AEEF · Magenta #EC008C · Green #7AC143 ·
   Orange #F47B20 · Dark Blue #2E3192
   ============================================================ */

/* ---------- Tokens ---------- */
/* 1.69.0 (speed audit): Lato is served by the app itself (Lato by Łukasz
   Dziedzic, SIL Open Font License 1.1, the fontsource build, latin and
   latin-ext). One origin less on a first visit, two render-blocking Google
   stylesheets less, and the worker precaches the files with the shell. */
/* 1.77.4: a fallback face with Lato's metrics, so the text drawn before Lato arrives sits where Lato will put it (the swap used to shift every line: CLS 0.34 on the housing page). Measured against Liberation Sans (Arial's metrics): the size-adjust is the ratio of the average letter width, the ascent and descent are Lato's hhea values over that ratio. Roboto (Android) is a touch wider than Arial; its numbers are estimated from that. */
@font-face { font-family: "Lato Fallback"; font-weight: 400; src: local("Arial"), local("Helvetica Neue"), local("Helvetica"), local("Liberation Sans"); size-adjust: 98.1%; ascent-override: 100.6%; descent-override: 21.7%; line-gap-override: 0%; }
@font-face { font-family: "Lato Fallback"; font-weight: 700; src: local("Arial Bold"), local("Arial-BoldMT"), local("Helvetica Neue Bold"), local("Liberation Sans Bold"); size-adjust: 92.8%; ascent-override: 106.4%; descent-override: 23%; line-gap-override: 0%; }
@font-face { font-family: "Lato Fallback"; font-weight: 900; src: local("Arial Black"), local("Arial Bold"), local("Arial-BoldMT"), local("Liberation Sans Bold"); size-adjust: 94.8%; ascent-override: 104.1%; descent-override: 22.5%; line-gap-override: 0%; }
@font-face { font-family: "Lato Fallback Roboto"; font-weight: 400; src: local("Roboto"); size-adjust: 96.2%; ascent-override: 102.6%; descent-override: 22.1%; line-gap-override: 0%; }
@font-face { font-family: "Lato Fallback Roboto"; font-weight: 700; src: local("Roboto Bold"); size-adjust: 92%; ascent-override: 107.3%; descent-override: 23.2%; line-gap-override: 0%; }
@font-face { font-family: "Lato"; font-style: normal; font-weight: 400; font-display: swap; src: url(/fonts/lato-latin-400-normal.woff2) format("woff2"); unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD; }
@font-face { font-family: "Lato"; font-style: normal; font-weight: 400; font-display: swap; src: url(/fonts/lato-latin-ext-400-normal.woff2) format("woff2"); unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF; }
@font-face { font-family: "Lato"; font-style: normal; font-weight: 700; font-display: swap; src: url(/fonts/lato-latin-700-normal.woff2) format("woff2"); unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD; }
@font-face { font-family: "Lato"; font-style: normal; font-weight: 700; font-display: swap; src: url(/fonts/lato-latin-ext-700-normal.woff2) format("woff2"); unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF; }
@font-face { font-family: "Lato"; font-style: normal; font-weight: 900; font-display: swap; src: url(/fonts/lato-latin-900-normal.woff2) format("woff2"); unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD; }
@font-face { font-family: "Lato"; font-style: normal; font-weight: 900; font-display: swap; src: url(/fonts/lato-latin-ext-900-normal.woff2) format("woff2"); unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF; }

:root {
  /* brand */
  --esn-cyan: #00AEEF;
  --esn-magenta: #EC008C;
  --esn-green: #7AC143;
  --esn-orange: #F47B20;
  --esn-dark: #2E3192;
  --navy-gradient: linear-gradient(160deg, #232668, var(--esn-dark) 55%, #171a4a);   /* the passport cover blue: the cover, the level-up banner, the promo swatch */
  /* surfaces and ink */
  --ink: #191a2e;
  --muted: #60637a;               /* 1.77.0: 4.97:1 on the grey surface (was 4.49, just under AA) */
  --bg: #f7f8fa;
  --card: #ffffff;
  --border: #e4e6ee;
  --surface2: #f2f3f8;
  --hover: #f8fafd;
  --grey-fill: #6b6e8a;             /* badge grey that white text can sit on (1.29.4) */
  /* brand colours as text, on light surfaces (1.29.4) */
  --accent-text: var(--esn-dark);   /* brand blue as TEXT - swapped for cyan in the dark theme (1.1.14) */
  --cyan-on-dark: #4dd0ff;          /* 1.77.0: cyan as text on the header and hero blues (6:1); the brand cyan is 4.2:1 there */
  --magenta-deep: #d4007d;          /* 1.77.0: magenta under white text (5.1:1; the brand magenta is 4.25) */
  --cyan-text: #007bb0;             /* 1.78.4 (audit): cyan as small text on white (4.7:1; the brand cyan is 2.5) */
  --orange-text: #b05209;           /* 1.78.4: orange as small text on white (5.2:1) and on its own tint (4.5:1) */
  --magenta-text: #d4007d;          /* 1.78.4: magenta as small text on white (5.1:1) */
  --on-bright: #12142a;             /* ink on ESN cyan, green and orange (white fails AA on all three) */
  --green-text: #3d7a14;
  --orange-text: #b4530b;
  --magenta-text: #d10078;
  --danger: #D7263D;                /* red = no / destructive (v1.4.0) */
  --danger-soft: rgba(215, 38, 61, 0.10);
  --lvl1: #5f627a;                  /* passport level 1 grey, readable on white (1.1.11) */
  /* radius: controls, cards, sheets */
  --r-sm: 8px;
  --r-md: 12px;
  --r-lg: 16px;
  --w-read: 760px;                 /* 1.78.4 (layout audit): a page that is read (guide, deal, FAQ, songbook, RSVP, the door) */
  --w-wide: 980px;                 /* 1.78.4: a page with two columns or a grid (account, passport, shop, housing) */
  --radius: var(--r-md);
  /* elevation */
  --shadow: 0 1px 2px rgba(25, 26, 46, 0.05), 0 3px 10px rgba(25, 26, 46, 0.06);
  --shadow-lg: 0 4px 10px rgba(25, 26, 46, 0.07), 0 12px 32px rgba(25, 26, 46, 0.10);
  --shadow-pop: var(--shadow-lg);   /* menus and popovers */
  /* focus (1.1.11): an ink ring on a background gap, visible on cyan, green and magenta controls in both themes */
  --ring: 2px solid var(--ink);
  --ring-gap: 0 0 0 2px var(--bg);
  --ring-soft: 0 0 0 3px rgba(0, 174, 239, .22);   /* the glow on text fields */
  /* motion */
  --t-fast: .12s;
  --t-base: .18s;
  --t-slow: .3s;
  /* 1.78.16: the motion scale of the transitions library the owner pointed at (transitions.dev),
     recreated here: one settling curve for what moves into place (dialogs, the avatars' lift), a
     small overshoot for pops, a strong spring for the avatars' return; quick closes, calm opens */
  --ease-settle: cubic-bezier(.22, 1, .36, 1);
  --ease-pop: cubic-bezier(.34, 1.36, .64, 1);
  --ease-spring: cubic-bezier(.34, 3.85, .64, 1);
  --dur-quick: .15s;
  --dur-fast: .25s;
  --dur-avatar: .32s;
  /* viz (1.13.0): four hues in a fixed order, validated for colour blindness on
     each surface (never cycled past four). Magnitude: one blue ramp. Status:
     reserved, always with an arrow or icon beside it. */
  --viz-1: #0b8ed9; --viz-2: var(--esn-magenta); --viz-3: #4a3aa7; --viz-4: #5a9a2c;
  --viz-gray: #c7cad8; --viz-grid: #e6e8f0; --viz-hit: rgba(11, 142, 217, .08);
  --viz-s1: #dbf0fb; --viz-s2: #b5e0f7; --viz-s3: #86caf1; --viz-s4: #4fb0e6; --viz-s5: #1e93d3; --viz-s6: #0f74ac; --viz-s7: #0a5580;
  --viz-good: #0ca30c; --viz-warn: #fab219; --viz-serious: #ec835a; --viz-critical: #d03b3b;
  /* maps (v1.5.0) and partner categories, pins, the globe (1.15.0) */
  --map-sea: #f6f9fd; --map-land: #e6e8f0; --map-lo: #d9f1fc; --map-hi: #0077b6; --map-bg: #e8ecf3;
  --cat-bar: var(--esn-orange); --cat-drinks: var(--esn-magenta); --cat-sport: var(--esn-green); --cat-transport: var(--esn-cyan); --cat-health: #6A3FB5;
  --cat-shop: #C98A00; --cat-hostel: #1F8A70; --cat-app: #B5532F; --cat-other: #6B7280; --pin-venue: var(--esn-dark);
  --globe-bg-0: #eef3fb; --globe-bg-1: #d7e3f4; --globe-sea-0: #edf4fd; --globe-sea-1: #c3d7ef;
  --globe-land: #fbfcfe; --globe-land-zoomed: #e4ebf5; --globe-lo: #a6d8f3; --globe-hi: #0b5fa5;
  --globe-line: rgba(46, 49, 146, .28); --globe-grat: rgba(46, 49, 146, .1); --globe-rim: rgba(46, 49, 146, .4);
  --globe-arc: rgba(0, 119, 200, .7); --globe-arc-sel: #d6007e; --globe-lbl: #14183a; --globe-halo: #ffffff;
  --globe-pt: #0077c8; --globe-focus: #14183a;
}
/* Dark mode: same structure, re-tokened */
html[data-theme="dark"] {
  color-scheme: dark;   /* native controls (selects, date pickers, scrollbars) in their dark variants instead of white boxes */
  --ink: #e8e9f6;
  --muted: #9b9ec0;
  --cyan-text: #00AEEF; --orange-text: #F47B20; --magenta-text: #ff66bf; /* 1.78.4: on the dark cards the brand colours pass; magenta needs a lift */
  --bg: #12132a;
  --card: #1b1d3d;
  --border: #2d3057;
  --surface2: #22244a;
  --hover: #22244a;
  --grey-fill: #5b5e80;
  --accent-text: var(--esn-cyan);
  --green-text: #9be36a;
  --orange-text: #ffb070;
  --magenta-text: #ff5fb8;
  --danger: #FF5C6E;
  --danger-soft: rgba(255, 92, 110, 0.16);
  --lvl1: #9a9cb5;
  --shadow: 0 1px 3px rgba(0, 0, 0, 0.5);
  --shadow-lg: 0 6px 20px rgba(0, 0, 0, 0.55);
  --viz-1: #1f97d8; --viz-2: #e8399a; --viz-3: #8a80dc; --viz-4: #63a63a;
  --viz-gray: #3a3d63; --viz-grid: #2c2f52; --viz-hit: rgba(31, 151, 216, .14);
  --viz-s1: #17304f; --viz-s2: #1a4570; --viz-s3: #1d5c92; --viz-s4: #2174b2; --viz-s5: #2a8fd0; --viz-s6: #4fb0e6; --viz-s7: #86caf1;
  --map-sea: #14162f; --map-land: #262a4f; --map-lo: #1d3f5c; --map-hi: #6fd0ff; --map-bg: #1c1e33;
  --cat-health: #9B6BE0; --cat-shop: #E0A526; --cat-hostel: #2FB597; --cat-app: #D9744F; --cat-other: #9AA0B8; --pin-venue: #8C93F5;
  --globe-bg-0: #1a2a66; --globe-bg-1: #0a1030; --globe-sea-0: #1b2c6b; --globe-sea-1: #0a1030;
  --globe-land: #26305e; --globe-land-zoomed: #1a2352; --globe-lo: #2a6db3; --globe-hi: #7ff0ff;
  --globe-line: rgba(127, 240, 255, .25); --globe-grat: rgba(127, 240, 255, .14); --globe-rim: rgba(127, 240, 255, .55);
  --globe-arc: rgba(160, 244, 255, .85); --globe-arc-sel: #ff7cc8; --globe-lbl: #ffffff; --globe-halo: #0a1030;
  --globe-pt: #7ff0ff; --globe-focus: #ffffff;
}
/* Inline accents that name the dark blue (a meeting in the calendar, the
   mark ticket, the organigram's board node carry --accent: var(--esn-dark))
   would sink into the navy background: any such element reads in ink. */
html[data-theme="dark"] [style*="--esn-dark"] { color: var(--ink) !important; }

/* ============================================================
   BASE: reset, fonts, motion defaults, view transitions
   ============================================================ */

/* ---------- Material Symbols (icons) ---------- */
/* 1.69.0: the icon stylesheet no longer blocks the first paint (index.html
   loads it as print and flips it to all once it is in). Until then the
   ligature names would show as words, so the icons stay invisible; the
   font's own block period takes over from there. */
html:not(.icons-css) .material-symbols-rounded { visibility: hidden; }
.material-symbols-rounded.mi-full { font-family: "Material Symbols Rounded Full", "Material Symbols Rounded"; }  /* 1.77.6: an icon the subset does not have, drawn with the full set once it is in */
.material-symbols-rounded {
  /* Own font-family declaration (hotfix 03/09): never depend on the class
     Google's stylesheet may or may not ship - only its @font-face. */
  font-family: "Material Symbols Rounded";
  font-weight: normal;
  font-style: normal;
  letter-spacing: normal;
  text-transform: none;
  white-space: nowrap;
  direction: ltr;
  -webkit-font-feature-settings: "liga";
  font-feature-settings: "liga";
  font-variation-settings: 'FILL' 0, 'wght' 500, 'GRAD' 0, 'opsz' 24;
  font-size: 20px;
  line-height: 1;
  vertical-align: -5px;
  display: inline-block;
  user-select: none;
}
.mi-sm { font-size: 16px; vertical-align: -4px; }

/* ---------- Base ---------- */
html[data-theme="dark"] select,
html[data-theme="dark"] input:not([type="checkbox"]):not([type="radio"]),
html[data-theme="dark"] textarea { background-color: var(--card); color: var(--ink); border-color: var(--border); }  /* 1.48.0: the colour only, so the search field keeps its magnifier */
/* Native-app feel */
* { box-sizing: border-box; margin: 0; padding: 0; -webkit-tap-highlight-color: transparent; }
html { -webkit-text-size-adjust: 100%; overscroll-behavior-x: none; background: var(--bg); touch-action: manipulation; }  /* 1.55.0: pinch zoom is back (WCAG 1.4.4); manipulation still drops the double-tap delay */
/* Backstop: nothing may ever push the page wider than the screen.
   'clip' (not 'hidden') keeps position:sticky working. */
body {
  font-family: "Lato", "Lato Fallback Roboto", "Lato Fallback", "Helvetica Neue", Arial, sans-serif;
  font-size: .95rem; /* 1.69.6: was 15px, which kept every paragraph at 15 px whatever text size the reader set; .95rem is 15.2 px by default */
  background: var(--bg);
  color: var(--ink);
  line-height: 1.6;
  /* Sticky footer: content area stretches, footer sits at the bottom */
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  overflow-x: clip;
  overscroll-behavior-x: none;
}
html[data-theme="dark"] body { background: var(--bg); }
#app {
  flex: 1 0 auto;
  width: 100%;
  overflow-x: clip;   /* 1.40.0: a page never scrolls sideways, whatever overflows is clipped */
}
.container { max-width: 1140px; margin: 0 auto; padding: 0 24px; }
.hidden { display: none !important; }
/* The hidden ATTRIBUTE must win over display rules on classes too (the
   dashboard's inbox strip showed '0 open student messages' because .attn's
   inline-flex beat the browser's [hidden] - 1.1.15). */
[hidden] { display: none !important; }
a { color: var(--esn-dark); text-decoration: none; }
html[data-theme="dark"] a { color: var(--esn-cyan); }
html[data-theme="dark"] .main-nav a { color: #d6d8f0; }  /* 1.77.0: not the cyan: 4.2:1 on the header blue */
html[data-theme="dark"] :is(.site-header, .site-footer, .g-hero, .g-final) a:not(.btn):not(.main-nav a) { color: var(--cyan-on-dark); }  /* 1.77.0: cyan as text on the blues reads 6:1 */
html[data-theme="dark"] .main-nav a.active { color: #fff; }
html[data-theme="dark"] a.deal-name-link { color: inherit; }  /* 1.78.13: a deal's name reads as its title, the card is the link */
p a:not(.btn), .form-hint a:not(.btn), .join-list a:not(.btn), li > span > a:not(.btn), .install-list li a, small a:not(.btn) { text-decoration: underline; text-underline-offset: 2px; }  /* 1.77.0: a link inside running text is told by more than its colour */
a:hover { text-decoration: underline; }
h1, h2, h3 { line-height: 1.25; }
input::placeholder, textarea::placeholder { color: var(--muted); opacity: 1; }  /* 1.55.0: full strength, readable (was 2.9:1) */  /* v0.109.1: Design pass — playbook fundamentals */
#app[data-enter] > * { animation: settleIn .28s ease backwards; }  /* 1.55.0: on arriving only, and nothing left behind: a kept transform misplaced fixed popovers. 1.69.2: settleIn starts visible (viewIn started at 0, and the staggered wait left the page dark for a moment) */
:root[data-vt] #app > * { animation: none; }  /* 1.55.0: the view transition already moves the page */
#app > *:nth-child(2) { animation-delay: .04s; }
#app > *:nth-child(3) { animation-delay: .08s; }
#app > *:nth-child(4) { animation-delay: .11s; }
#app > *:nth-child(n+5) { animation-delay: .14s; }
details[open] > *:not(summary) { animation: viewIn .22s ease both; }
/* 1.78.7: lists arrive card by card (the same settle as the page), and a card you tap gives a little under the finger */
@media (prefers-reduced-motion: no-preference) {
  #app[data-enter] :is(.agenda-item, .tk-item, .deal-card, .sh-card, .stat-card, .kpi, .news-strip) { animation: settleIn .32s ease backwards; }
  #app[data-enter] :is(.agenda-item, .tk-item, .deal-card, .sh-card, .stat-card, .kpi, .news-strip):nth-child(2) { animation-delay: .04s; }
  #app[data-enter] :is(.agenda-item, .tk-item, .deal-card, .sh-card, .stat-card, .kpi, .news-strip):nth-child(3) { animation-delay: .08s; }
  #app[data-enter] :is(.agenda-item, .tk-item, .deal-card, .sh-card, .stat-card, .kpi, .news-strip):nth-child(4) { animation-delay: .12s; }
  #app[data-enter] :is(.agenda-item, .tk-item, .deal-card, .sh-card, .stat-card, .kpi, .news-strip):nth-child(5) { animation-delay: .16s; }
  #app[data-enter] :is(.agenda-item, .tk-item, .deal-card, .sh-card, .stat-card, .kpi, .news-strip):nth-child(n+6) { animation-delay: .2s; }
}
@media (hover: none) and (prefers-reduced-motion: no-preference) {
  :is(.event-card, .agenda-item, .tk-item, .deal-card, .news-strip, .pp-strip, .sh-card, .wk-day.has) { transition: transform .16s ease, box-shadow .2s ease; }
  :is(.event-card, .agenda-item, .tk-item, .deal-card, .news-strip, .pp-strip, .sh-card, .wk-day.has):active { transform: scale(.985); }
}
/* Anchored scrolls land below the sticky header instead of underneath it */
[id] { scroll-margin-top: 72px; }  /* v0.130: audit fixes */
/* Disclosure summaries are buttons - act like it */
summary { cursor: pointer; }
/* Data saver: no motion, no decorative images */
html.save-data *, html.save-data *::before, html.save-data *::after {
  animation-duration: .001ms !important; animation-iteration-count: 1 !important; transition-duration: .001ms !important;
}  /* 1.29.2: small app comforts */
@media (max-width: 820px) {
  body { padding-bottom: calc(84px + env(safe-area-inset-bottom)); }  /* Responsive */
  .container { padding: 0 16px; }
  /* iOS zooms the page when focusing inputs smaller than 16px —
     the single biggest "this is a website" tell. 820px matches the
     mobile layout breakpoint (v0.130; was 720, leaving iPads zooming). */
  input, select, textarea { font-size: 16px !important; }  /* v0.109.1: Design pass — playbook fundamentals */
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
}
@media (display-mode: standalone) {
  html, body { overscroll-behavior-y: contain; }  /* v0.109.1: Design pass — playbook fundamentals */
}

/* ---- View Transitions (1.9.0) ----------------------------------------
   The header and the bottom bar are named, which takes them out of the root
   snapshot: they stay put while the page underneath changes, which is the
   whole difference between an app and a series of page loads. Everything
   else is the root, and the root cross-fades with a small rise.
   Browsers without the API never see any of this and keep .page-anim. */
/* 1.38.0: while the transition plays, its snapshots sit over the page and
   would take the taps; let them pass through, so a second tab tap during
   the fade still counts. */
::view-transition { pointer-events: none; }
::view-transition-old(root) { animation: vt-fade-out .14s ease both; }
::view-transition-new(root) { animation: vt-rise-in .22s cubic-bezier(.2, .7, .3, 1) both; }
/* Show only the new chrome: the two snapshots are identical, so stacking
   them would just cost a repaint. */
::view-transition-old(esn-header), ::view-transition-old(esn-bottombar) { display: none; }
::view-transition-new(esn-header), ::view-transition-new(esn-bottombar) { animation: none; }
@media (min-width: 821px) {
  @media (prefers-reduced-motion: no-preference) {
    ::view-transition-group(esn-navpill-desk) { animation-duration: .26s; animation-timing-function: cubic-bezier(.2, .7, .3, 1); }  /* 1.41.0: The bars */
    ::view-transition-old(esn-navpill-desk) { display: none; }
    ::view-transition-new(esn-navpill-desk) { animation: none; }
  }
}
/* 1.69.2: the tapped card's picture morphs into the event banner and back.
   Both snapshots fill the moving box (no cross-fade dip: the new one is
   simply on top), so the picture scales from card to banner in one move. */
::view-transition-group(esn-hero) { animation-duration: .3s; animation-timing-function: cubic-bezier(.2, .7, .3, 1); z-index: 3; }
::view-transition-old(esn-hero),
::view-transition-new(esn-hero) { animation: none; mix-blend-mode: normal; height: 100%; width: 100%; object-fit: cover; overflow: clip; }
/* 1.69.3: no counterpart (the card is off screen, or the page came from a
   deep link): the picture fades instead of flying nowhere */
::view-transition-old(esn-hero):only-child { animation: vt-fade-out .14s ease both; }
::view-transition-new(esn-hero):only-child { animation: vt-rise-in .22s cubic-bezier(.2, .7, .3, 1) both; }
/* 1.69.2: a chip tap on the home page moves the cards to their new places;
   the page around them stays put. */
:root[data-vt="list"]::view-transition-old(root),
:root[data-vt="list"]::view-transition-new(root) { animation: none; }
@media (prefers-reduced-motion: reduce) {
  ::view-transition-group(*),
  ::view-transition-old(*),
  ::view-transition-new(*) { animation: none !important; }
}
@media (max-width: 820px) {
  @media (prefers-reduced-motion: no-preference) {
    ::view-transition-group(esn-navpill) { animation-duration: .28s; animation-timing-function: cubic-bezier(.2, .7, .3, 1); }  /* 1.41.0: The bars */
    ::view-transition-old(esn-navpill) { display: none; }
    ::view-transition-new(esn-navpill) { animation: none; }
    :root[data-vt="tab-right"]::view-transition-old(root) { animation: vt-slide-out-left .18s ease both; }
    :root[data-vt="tab-right"]::view-transition-new(root) { animation: vt-slide-in-right .24s cubic-bezier(.2, .7, .3, 1) both; }
    :root[data-vt="tab-left"]::view-transition-old(root) { animation: vt-slide-out-right .18s ease both; }
    :root[data-vt="tab-left"]::view-transition-new(root) { animation: vt-slide-in-left .24s cubic-bezier(.2, .7, .3, 1) both; }
    :root[data-vt="push"]::view-transition-old(root) { animation: vt-push-out .22s ease both; }
    :root[data-vt="push"]::view-transition-new(root) { animation: vt-push-in .28s cubic-bezier(.2, .7, .3, 1) both; }
    :root[data-vt="pop"]::view-transition-old(root) { animation: vt-pop-out .24s cubic-bezier(.4, 0, .8, .6) both; z-index: 2; }
    :root[data-vt="pop"]::view-transition-new(root) { animation: vt-pop-in .24s ease both; }
    /* The page moves the way you went: sideways between tabs, in from the
     right into a deeper page, out to the right on Back (html[data-vt]). */
  }
}

/* ---------- Design pass (v0.109.1) — playbook fundamentals ----------
   1. Numbers are DATA: fixed-width numerals everywhere values appear, so
      columns line up and counters don't jiggle when they tick.
   2. Stat cards share one anatomy: big number, breathing room, micro-label.
   3. Forms respond: hover hints before focus, calm transitions.
   4. Settings rows: comfortable touch height, chevron nudge on hover. */
/* Live check-in confirmation on the ticket page (v0.107) */
.checkin-flash { animation: checkinPulse .5s ease; }

/* ---------- Accessibility helpers (v0.131) ---------- */
/* Visually hidden but focusable (keyboard-reachable file inputs) */
.vh-input {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
/* Skip link: invisible until focused */
.skip-link {
  position: absolute; left: 8px; top: -48px; z-index: 200;
  background: var(--esn-dark); color: #fff; font-weight: 800;
  padding: 10px 16px; border-radius: 0 0 10px 10px; transition: top .15s ease;
}
.skip-link:focus { top: 0; }
/* Unread badge on the admin Inbox tab */
.tab-badge {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 18px; height: 18px; padding: 0 5px; margin-left: 5px;
  border-radius: 9px; background: #d10078; color: #fff;  /* 1.55.0: contrast */
  font-size: .7rem; font-weight: 900; vertical-align: middle;
}
.tab-badge.is-danger { background: var(--danger); }  /* 1.78.16: critical errors on the Settings tab (red is blocked) */

/* ============================================================
   TYPOGRAPHY: headings, titles, rich text, the person and the country
   ============================================================ */

/* ---------- Headings: one scale (1.29.4) ---------- */
.event-detail-banner h1 { font-weight: 900; display: flex; align-items: center; gap: 10px; flex-wrap: wrap; font-size: 1.45rem; }
.tkt-top h1 {
  font-weight: 900;
  line-height: 1.2;
  overflow-wrap: anywhere;
  text-shadow: none;
  font-size: 1.3rem;
  margin: 8px 0 6px;
}  /* 1.1.33: The ticket */
#app h1 { font-size: 1.45rem; line-height: 1.2; margin: 0 0 8px; letter-spacing: -.01em; }
#app h2:not(.section-title) { font-size: 1.15rem; line-height: 1.25; }
#app h3:not(.section-title):not(.group-title):not(.settings-group) { font-size: 1rem; line-height: 1.3; }
#app h4 { font-size: .95rem; line-height: 1.3; }
@media (min-width: 821px) {
  #app h1 { font-size: 1.7rem; }
  .event-detail-banner h1 { font-size: 1.7rem; }
}

/* ---------- Section headings ---------- */
.section-title {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 28px 0 14px;
  font-size: 1.3rem;
  font-weight: 900;
  letter-spacing: .2px;
}
.section-title::before {
  content: "";
  width: 5px;
  height: 1.15em;
  border-radius: 3px;
  background: var(--esn-cyan);
  flex: none;
}
/* Sub-section headings: one class instead of 35 inline overrides -
   keeps a visible hierarchy step on mobile too */
.section-title.sm { font-size: 1.05rem; }  /* v0.131 */
.section-title[id] { scroll-margin-top: 64px; }  /* 1.1.32: Section jump bar */
.section-title + p.form-hint { max-width: 78ch; }  /* 1.14.1: one button */
@media (max-width: 820px) {
  .section-title { font-size: 1.05rem; margin: 22px 0 12px; }  /* Responsive */
}

/* ---------- Rich text ---------- */
.rich { font-size: .95rem; overflow-wrap: anywhere; }
.rich p { margin: 0 0 12px; }
.rich ul { margin: 0 0 12px 20px; }
.rich li { margin-bottom: 4px; }
.rich h3 { margin: 18px 0 8px; font-size: 1.05rem; font-weight: 900; color: var(--esn-dark); }
html[data-theme="dark"] .rich h3 { color: var(--esn-cyan); }
.rich a { font-weight: 700; }
.rich ol { margin: 0 0 12px 22px; }  /* 1.32.0: minutes formatting bar */
.rich u { text-decoration-thickness: 2px; text-underline-offset: 2px; }

/* ---------- One person, printed the same way everywhere (1.1.37) ---------- */
.person { display: inline-flex; align-items: center; gap: 7px; min-width: 0; vertical-align: middle; }
.person-txt { display: flex; flex-direction: column; min-width: 0; line-height: 1.25; }
.person-name { font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.person-txt small { font-weight: 500; }
.person-link { color: inherit; }
.person-link:hover .person-name, .person-link:focus-visible .person-name {
  color: var(--accent-text);
  text-decoration: underline;
  text-underline-offset: 2px;
}
/* A row of people (attendance, a shift slot) wraps instead of overflowing. */
.person-list { display: flex; flex-wrap: wrap; gap: 6px 14px; align-items: center; }

/* ---------- Group titles ---------- */
/* Home: sub-group headers inside the upcoming list ("This week" / "Later") */
.group-title {
  font-size: .8rem;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: .8px;
  color: var(--muted);
  margin: 18px 0 10px;
  display: flex;
  align-items: center;
  gap: 10px;
}
.group-title::after { content: ""; flex: 1; height: 1px; background: var(--border); }
.group-title:first-child { margin-top: 4px; }
/* Desktop: the buy box follows you while reading long event pages */
/* Desktop: two-column account layout (card left, menu right) */
.account-left { display: flex; flex-direction: column; gap: 14px; min-width: 0; }
.account-right { display: flex; flex-direction: column; gap: 12px; min-width: 0; }
@media (min-width: 821px) {
  .account-left { grid-column: 1; position: sticky; top: 86px; }
  /* the short column stays in view */
  .account-right { grid-column: 2; }
  .m-only-row { display: none; }
}
@media (max-width: 820px) {
  .account-left, .account-right { display: contents; }
  .account-left > .form-card { order: 1; }
}

/* ---------- Country + flag, printed the same way everywhere (1.1.37) ---------- */
.flagged { display: inline-flex; align-items: baseline; gap: 5px; min-width: 0; }
.flag-em {
  /* Emoji fonts vary wildly in metrics; a fixed box keeps columns of
     countries aligned instead of ragged. */
  font-family: "Apple Color Emoji", "Segoe UI Emoji", "Noto Color Emoji", sans-serif;
  font-size: 1.05em;
  line-height: 1;
  flex: none;
}
.esncard-value .flag-em { font-size: 1em; }

/* ============================================================
   SHELL: header, navigation, bars, footer
   ============================================================ */

/* ---------- Header ---------- */
.site-header {
  background: var(--esn-dark);
  color: #fff;
  position: sticky;
  top: 0;
  z-index: 50;
  border-bottom: 3px solid var(--esn-cyan);
}
.header-inner {
  display: flex;
  align-items: center;
  gap: 20px;
  min-height: 62px;
}
.brand { display: flex; align-items: center; gap: 12px; color: #fff; flex: none; }
.brand:hover { text-decoration: none; }
.brand-star { width: 30px; height: 30px; }
.brand-logo {
  height: 38px;
  width: 38px;
  object-fit: contain;
}
.brand-text { font-size: 1.05rem; letter-spacing: .2px; white-space: nowrap; }
.brand-text strong { color: var(--cyan-on-dark); }  /* 1.77.0: the lighter cyan reads 6:1 on the header blue (the brand cyan is 4.2) */
.main-nav { display: flex; gap: 2px; flex: 1; min-width: 0; height: 62px; align-items: stretch; }
.main-nav a {
  color: #d6d8f0;
  padding: 0 13px;
  white-space: nowrap;
  display: flex;
  align-items: center;
  font-weight: 700;
  font-size: .8rem;
  letter-spacing: .6px;
  text-transform: uppercase;
  border-bottom: 3px solid transparent;
  margin-bottom: -3px;
  touch-action: manipulation;
  -webkit-user-select: none;
  user-select: none;
}
.main-nav a:hover { color: #fff; text-decoration: none; }
.main-nav a.active { color: #fff; border-bottom-color: var(--esn-cyan); }
.header-actions { display: flex; align-items: center; gap: 10px; flex: none; }
.user-chip { display: flex; align-items: center; gap: 6px; font-size: .9rem; white-space: nowrap; }
.user-chip #user-name { max-width: 160px; overflow: hidden; text-overflow: ellipsis; }
/* The bar must always show every item. fitHeader() in app.js measures the
   nav and sheds weight in this order until it fits: the name, the nav
   icons, tighter padding, the brand text - never a hidden scroll. */
.site-header.hdr-noname #user-name { display: none; }
.site-header.hdr-noicons .main-nav a .material-symbols-rounded { display: none; }
.site-header.hdr-tight .main-nav a { padding: 0 9px; font-size: .75rem; letter-spacing: .4px; }
.site-header.hdr-tight .header-inner { gap: 14px; }
.site-header.hdr-nobrand .brand-text { display: none; }
.user-avatar { width: 30px; height: 30px; border-radius: 50%; border: 2px solid var(--esn-cyan); display: block; }
.user-link { display: flex; align-items: center; gap: 8px; color: #fff; }
.user-link:hover { text-decoration: none; opacity: .85; }
.user-link.active .user-avatar { border-color: #fff; box-shadow: 0 0 0 2px var(--esn-cyan); }
.nav-toggle { display: none; background: none; border: none; color: #fff; font-size: 1.45rem; cursor: pointer; }
/* ONE ring: the passport-level colour replaces the default cyan border
   (v0.136) - no double circle around the avatar. */
.user-avatar.pp-ring { border-color: var(--pp-c, var(--esn-cyan)); }  /* v0.101: passport gamification */
.user-avatar.pp-ring-1 { --pp-c: #9a9cb5; }
.user-avatar.pp-ring-2 { --pp-c: var(--esn-cyan); }
.user-avatar.pp-ring-3 { --pp-c: var(--esn-green); }
.user-avatar.pp-ring-4 { --pp-c: var(--esn-orange); }
.user-avatar.pp-ring-5 { --pp-c: var(--esn-magenta); }
/* Desktop nav icons + theme toggle */
.main-nav a .material-symbols-rounded { font-size: 16px; vertical-align: -4px; margin-right: 5px; opacity: .85; }  /* v1.1.6: Navigation progress bar */
.user-avatar.pp-ring-6 { --pp-c: #D4A017; }  /* 1.29.0: passport 3 */
@media (min-width: 821px) {
  @media (prefers-reduced-motion: no-preference) {
    .main-nav > a.active { view-transition-name: esn-navpill-desk; }  /* 1.41.0: The bars */
  }
}
@media (min-width: 821px) {
  .main-nav { gap: 4px; align-items: center; }
  .main-nav > a {
    height: 38px; padding: 0 14px; border-radius: 999px; margin: 0; border-bottom: 0;
    font-size: .85rem; font-weight: 700; letter-spacing: .1px; text-transform: none; color: #d6d8f0;
    transition: background var(--t-base) ease, color var(--t-base) ease;
  }
  .main-nav > a .material-symbols-rounded { font-size: 19px; margin-right: 6px; opacity: .9; vertical-align: -5px; }
  .main-nav > a:hover { background: rgba(255, 255, 255, .09); color: #fff; }
  .main-nav > a.active { background: rgba(0, 174, 239, .22); color: #fff; box-shadow: inset 0 0 0 1px rgba(0, 174, 239, .35); }
  .main-nav > a.active .material-symbols-rounded { opacity: 1; font-variation-settings: "FILL" 1, "wght" 500, "GRAD" 0, "opsz" 24; }
  .main-nav .nav-menu-btn { height: 38px; margin-bottom: 0; border-bottom: 0; border-radius: 999px; text-transform: none; font-size: .85rem; letter-spacing: .1px; }
  /* 1.65.1: a page that lives in More lights the button like the other pills, never with the old tab underline */
  .main-nav .nav-menu-btn.active { background: rgba(0, 174, 239, .22); color: #fff; box-shadow: inset 0 0 0 1px rgba(0, 174, 239, .35); }
  .main-nav .nav-menu-btn.active > .material-symbols-rounded:first-child { opacity: 1; font-variation-settings: "FILL" 1, "wght" 500, "GRAD" 0, "opsz" 24; }
}
@media (max-width: 820px) {
  /* Slim native-style app bar: page title + avatar, no logo, no footer */
  .site-header {
    padding-top: env(safe-area-inset-top);
    border-bottom-width: 2px;
  }  /* Responsive */
  .header-inner { min-height: 50px; gap: 12px; }
  .brand { display: none; }
  .main-nav, .nav-toggle { display: none !important; }
  /* sign-out lives on the Profile screen */
  .header-actions { margin-left: auto; }
}
@media (prefers-reduced-motion: no-preference) {
  .site-header { view-transition-name: esn-header; }  /* 1.9.0: View Transitions */
}

/* ---------- Manage menu (desktop, 1.1.41) ----------
   The team's tools behind one button, so a board member's bar has five
   items instead of nine and never needs fitHeader() to shrink it. */
.nav-menu { position: relative; display: flex; align-items: stretch; }
.nav-menu-btn {
  display: flex; align-items: center; gap: 0;
  padding: 0 13px; margin-bottom: -3px;
  background: none; border: 0; border-bottom: 3px solid transparent;
  color: #d6d8f0; font: inherit; font-weight: 700; font-size: .8rem; letter-spacing: .6px; text-transform: uppercase;
  cursor: pointer; white-space: nowrap;
}
.nav-menu-btn:hover, .nav-menu-btn[aria-expanded="true"] { color: #fff; }
.nav-menu-btn.active { color: #fff; border-bottom-color: var(--esn-cyan); }
.nav-menu-btn .material-symbols-rounded { font-size: 16px; vertical-align: -4px; margin-right: 5px; opacity: .85; }
.nav-menu-btn .nav-caret { margin: 0 0 0 2px; font-size: 18px; transition: transform .15s ease; }
.nav-menu-btn[aria-expanded="true"] .nav-caret { transform: rotate(180deg); }
.nav-menu-list {
  position: absolute; top: calc(100% + 3px); left: 0; z-index: 70;
  min-width: 250px; padding: 6px;
  background: var(--card); color: var(--ink);
  border: 1px solid var(--border); border-radius: var(--r-md);
  box-shadow: 0 12px 34px rgba(0, 0, 0, .28);
  animation: sheet-in .12s ease-out;
}
.nav-menu-list[hidden] { display: none; }
/* Specific enough to beat .main-nav a, which paints links for the dark bar. */
.main-nav .nav-menu-list a {
  display: grid; grid-template-columns: 22px 1fr; column-gap: 10px; align-items: center; row-gap: 1px;
  height: auto; padding: 9px 10px; margin: 0; border: 0; border-radius: var(--r-sm);
  color: var(--ink); font-weight: 700; font-size: .9rem; letter-spacing: 0; text-transform: none; text-decoration: none;
  white-space: normal;
}
.main-nav .nav-menu-list .nav-menu-lbl { grid-column: 2; line-height: 1.2; }
.main-nav .nav-menu-list a small { grid-column: 2; font-weight: 500; font-size: .75rem; color: var(--muted); letter-spacing: 0; text-transform: none; }
.main-nav .nav-menu-list a .material-symbols-rounded { grid-row: 1 / span 2; font-size: 20px; margin: 0; opacity: 1; color: var(--accent-text); }
.main-nav .nav-menu-list a:hover { background: var(--surface2); color: var(--ink); text-decoration: none; outline: none; border: 0; }
.main-nav .nav-menu-list a:focus-visible { background: var(--surface2); color: var(--ink); text-decoration: none; outline: none; border: 0; box-shadow: inset 0 0 0 2px var(--ink); }  /* 1.55.0: a keyboard can see where it is */
.main-nav .nav-menu-list a.active { background: rgba(0, 174, 239, .14); border: 0; }
.site-header.hdr-noicons .nav-menu-btn > .material-symbols-rounded:first-child { display: none; }
.site-header.hdr-tight .nav-menu-btn { padding: 0 9px; font-size: .75rem; letter-spacing: .4px; }

/* ---------- App bar helpers: back arrow, mobile title ---------- */
/* Back arrow in the phone app bar - only on pages below a hub (1.1.41). */
.mobile-back { display: none; }
/* Mobile-only / desktop-only helpers */
.m-only { display: none; }
.mobile-title { display: none; }
@media (max-width: 820px) {
  /* Helpers */
  .m-only { display: block; }  /* Responsive */
  .mobile-back {
    display: flex; align-items: center; justify-content: center;
    width: 40px; height: 40px; margin-left: -10px; border-radius: 50%;
    color: #fff; text-decoration: none;
  }
  .mobile-back:active { background: rgba(255, 255, 255, .14); }
  .mobile-back .material-symbols-rounded { font-size: 24px; }
  .mobile-title {
    display: block;
    flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    font-size: 1.05rem;
    font-weight: 900;
    color: #fff;
    letter-spacing: .2px;
    user-select: none; -webkit-user-select: none; -webkit-tap-highlight-color: transparent; /* 1.43.0: five taps wake the dragon; no text selection on the way */
  }
}

/* ---- BETA ---- */
.beta-chip {
  background: var(--esn-orange);
  color: var(--on-bright);  /* 1.55.0: contrast */
  font-size: .75rem;
  font-weight: 800;
  letter-spacing: 0.06em;
  padding: 2px 7px;
  border-radius: 999px;
  margin-left: 8px;
  align-self: center;
}
.beta-banner {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  background: #fff7e8;
  border-bottom: 1px solid #f2d9a8;
  color: #6b4e0e;
  font-size: .85rem;
  padding: 8px 14px;
  text-align: center;
}
html[data-theme="dark"] .beta-banner {
  background: #2c2413;
  border-bottom-color: #4d3d18;
  color: #e8c87a;
}
.beta-banner code { font-weight: 700; }
.beta-banner button {
  background: none;
  border: none;
  color: inherit;
  font-size: 1rem;
  cursor: pointer;
  padding: 2px 6px;
}
/* Site banner kinds (board-configured, Admin -> Settings -> Site banner) */
.beta-banner.beta-banner-info { background: var(--esn-dark); color: #fff; }  /* v0.131 */
.beta-banner.beta-banner-info code { background: rgba(255,255,255,.15); }

/* ---------- View as (1.40.0) ---------- */
/* View as (1.40.0): a superadmin looking at the app as another role. */
.view-as-bar { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 14px; padding: 8px 16px; background: var(--esn-orange); color: var(--on-bright); font-size: .85rem; }  /* 1.55.0: dark ink for contrast */
.view-as-bar .material-symbols-rounded { vertical-align: -3px; }
.view-as-bar a { color: var(--on-bright); text-decoration: underline; }
.view-as-bar button { margin-left: auto; border: 1px solid rgba(18, 20, 42, .5); background: transparent; color: var(--on-bright); border-radius: 999px; padding: 4px 12px; font: inherit; font-weight: 700; cursor: pointer; }

/* ---------- Social icons ---------- */
/* Footer social icons — only the links the board filled in are rendered */
.footer-socials {
  display: flex;
  justify-content: center;
  gap: 18px;
  padding: 4px 0 14px;
}
.footer-socials a {
  color: rgba(255, 255, 255, .75);
  display: inline-flex;
  transition: color .15s, transform .15s;
}
.footer-socials a:hover { color: #fff; transform: translateY(-2px); }
.footer-socials svg, .footer-socials .material-symbols-rounded { width: 22px; height: 22px; font-size: 20px; }
/* Same icons inside light cards (Office page) */
.socials-row { display: flex; gap: 16px; align-items: center; }
.socials-row a { color: var(--esn-cyan); display: inline-flex; transition: transform .15s; }
.socials-row a:hover { transform: translateY(-2px); }
.socials-row svg, .socials-row .material-symbols-rounded { width: 21px; height: 21px; font-size: 20px; }

/* ---------- Mobile bottom nav ---------- */
.bottom-nav .material-symbols-rounded { font-size: 24px; vertical-align: 0; }
/* Bottom-nav "More" sheet (1.1.17): everything the five tabs can't fit */
.nav-more { background: none; border: 0; color: #cfd2f2; font-family: inherit; font-size: .75rem; font-weight: 700; display: none; flex-direction: column; align-items: center; gap: 2px; padding: 5px 12px; border-radius: 10px; cursor: pointer; }  /* 1.1.15: Settings markers */
.nav-more span { font-size: 1.3rem; line-height: 1; }
.nav-more.active { color: #fff; background: rgba(0, 174, 239, .3); }
.nav-sheet { position: fixed; inset: 0; z-index: 70; background: rgba(0,0,0,.45); display: flex; align-items: flex-end; }
.nav-sheet-card { background: var(--card); color: var(--ink); width: 100%; border-radius: 18px 18px 0 0; padding: 14px 16px calc(20px + env(safe-area-inset-bottom)); box-shadow: 0 -8px 30px rgba(0,0,0,.35); animation: sheet-in .18s ease-out; }
.nav-sheet-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(96px, 1fr)); gap: 8px; margin-top: 10px; }
.nav-sheet-grid a { display: flex; flex-direction: column; align-items: center; gap: 4px; padding: 12px 6px; border: 1px solid var(--border); border-radius: var(--r-md); text-decoration: none; color: var(--ink); font-size: .8rem; font-weight: 700; min-height: 64px; justify-content: center; text-align: center; }
.nav-sheet-grid a.active { border-color: var(--esn-cyan); background: rgba(0,174,239,.12); }
.bottom-nav {
  display: none;
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  background: var(--esn-dark);
  z-index: 60;
  justify-content: space-around;
  padding: 6px 4px calc(6px + env(safe-area-inset-bottom));
  box-shadow: 0 -2px 12px rgba(0, 0, 0, .3);
}
.bottom-nav a {
  color: #cfd2f2;
  font-size: .75rem;
  font-weight: 700;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  padding: 5px 12px;
  border-radius: 10px;
  text-decoration: none;
  touch-action: manipulation;
  -webkit-user-select: none;
  user-select: none;
}
.bottom-nav a span { font-size: 1.3rem; line-height: 1; }
.bottom-nav a.active { color: #fff; background: rgba(0, 174, 239, .3); }
.bottom-nav a:hover { text-decoration: none; }
.bottom-nav a:focus-visible, .nav-more:focus-visible { outline: none; box-shadow: none; }  /* 1.78.7: the keyboard ring sits on the icon's pill, not as a box round the whole tab */
.bottom-nav a:focus-visible span, .nav-more:focus-visible span { box-shadow: 0 0 0 2px #fff; }
html[data-theme="dark"] .bottom-nav a { color: #b9bde6; }  /* 1.78.7: the dark link rule (cyan) made the labels 4.2:1 on the bar */
html[data-theme="dark"] .bottom-nav a.active { color: #fff; }
@media (max-width: 820px) {
  /* 1.69.1: solid. The bar used to be see-through with a 14px backdrop blur,
     which re-blurs everything scrolling under it on every frame: the one
     fixed element that costs weak Androids the most while scrolling. */
  .bottom-nav { display: flex; background: var(--esn-dark); border-top: 1px solid rgba(255, 255, 255, .08); box-shadow: 0 -6px 24px rgba(0, 0, 0, .28); padding: 6px 2px calc(8px + env(safe-area-inset-bottom)); justify-content: space-evenly; }  /* Responsive */
  .nav-more { display: flex; }
  .bottom-nav a, .nav-more {
    position: relative; flex: 1 1 0; min-width: 0; max-width: 92px; padding: 2px 2px 3px; border-radius: var(--r-md); gap: 3px;
    color: #b9bde6; font-size: .75rem; font-weight: 600; letter-spacing: .2px; background: none;
    -webkit-tap-highlight-color: transparent;
  }  /* 1.41.0: The bars */
  .bottom-nav a span, .nav-more span {
    display: inline-flex; align-items: center; justify-content: center;
    width: min(56px, 100%); height: 30px; border-radius: 999px; font-size: 1.3rem; line-height: 1; /* 1.69.6: shrinks on a narrow or big-text screen */
    transition: background .22s ease, transform var(--t-base) cubic-bezier(.2, .7, .3, 1.4), color .2s ease;
    font-variation-settings: "FILL" 0, "wght" 500, "GRAD" 0, "opsz" 24;
  }
  .bottom-nav a.active, .nav-more.active { color: #fff; background: none; font-weight: 800; }
  .bottom-nav a.active span, .nav-more.active span {
    background: rgba(0, 174, 239, .34); color: #fff;
    font-variation-settings: "FILL" 1, "wght" 500, "GRAD" 0, "opsz" 24;
  }
  .bottom-nav a:active span, .nav-more:active span { transform: scale(.88); }
  .bottom-nav a:active, .nav-more:active { transform: none; }
}
/* 1.69.6: under 320 px of width (a small phone, or any phone with big text)
   six labels cannot fit: only the active tab keeps its word on screen; the
   others keep it for screen readers (size 0, still in the text) */
@media (max-width: 320px) {
  .bottom-nav a:not(.active), .nav-more:not(.active) { font-size: 0; }
}
@media (prefers-reduced-motion: no-preference) {
  .bottom-nav { view-transition-name: esn-bottombar; }  /* 1.9.0: View Transitions */
}
@media (max-width: 820px) {
  @media (prefers-reduced-motion: no-preference) {
    .bottom-nav a.active span { view-transition-name: esn-navpill; }  /* 1.41.0: The bars */
  }
}

/* ---- 1.25.0: offline, explained ---- */
.offline-strip { display: flex; align-items: center; gap: 10px; padding: 8px 16px; background: var(--esn-orange); color: var(--on-bright); font-weight: 700; font-size: .85rem; }  /* 1.55.0: dark ink, white was 2.7:1 */
.offline-strip span { flex: 1; min-width: 0; }
.offline-strip .btn { border-color: rgba(18, 20, 42, .45); color: var(--on-bright); }
.offline-hub { max-width: var(--w-read); margin: 0 auto; }
.offline-hub-head { text-align: center; padding: 18px 0 14px; }
.offline-hub-head .material-symbols-rounded { font-size: 44px; color: var(--esn-orange); }
.offline-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: 10px; }
.offline-tile { display: flex; flex-direction: column; align-items: center; gap: 8px; padding: 16px 10px; border-radius: var(--r-md); background: var(--card); border: 1px solid var(--border); color: var(--ink); text-decoration: none; font-weight: 700; font-size: .9rem; text-align: center; }
.offline-tile .material-symbols-rounded { font-size: 28px; color: var(--esn-cyan); }
.offline-tile:hover { border-color: var(--esn-cyan); text-decoration: none; }

/* ---------- Footer ---------- */
.site-footer { background: var(--esn-dark); color: #c9ccec; margin-top: 40px; font-size: .85rem; border-top: 3px solid var(--esn-cyan); }
/* 1.75.0: the three towers of Ghent (towersHtml, the template in index.html) */
.towers { display: block; line-height: 0; }
.towers svg { display: block; width: 100%; height: auto; }
.towers-gate { color: var(--esn-cyan); opacity: .55; max-width: 360px; margin: 0 auto 10px; }
.esncard-sky { position: absolute; left: 46%; right: 3%; bottom: 4%; color: var(--esn-dark); opacity: .11; pointer-events: none; }  /* 1.76.1: on the right, subtle */
.esncard-sky svg { stroke-width: 4; }
.esncard-right > :not(.esncard-sky) { position: relative; }
.g-hero-art { display: block; width: calc(100% + 36px); height: auto; aspect-ratio: 1200 / 460; margin: -18px -18px 14px; }  /* 1.78.9: the skyline's own shape on a phone; on a laptop the drawing keeps itself whole (meet) and its ground runs to the edges */
.hz-hero-art { display: block; width: calc(100% + 40px); height: auto; aspect-ratio: 1200 / 460; margin: -18px -20px 14px; background: linear-gradient(180deg, #232668, #2E3192); }
.hz-hero > :not(.hz-hero-art) { position: relative; }
@media (min-width: 760px) { .g-carousel > div { flex-basis: 300px; } .g-carousel { padding: 4px 2px 10px; margin: 0; scroll-padding: 0 2px; } .g-hero-art { height: 320px; aspect-ratio: auto; } .hz-hero-art { height: 260px; aspect-ratio: auto; } }
.footer-inner {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 26px;
  padding: 36px 24px;
}
.footer-star { width: 38px; height: 38px; margin-bottom: 8px; }
.footer-logo {
  height: 72px;
  width: auto;
  object-fit: contain;
  margin-bottom: 10px;
}
.site-footer a { color: #7fdcff; }
.footer-about { max-width: 300px; }
.footer-est { margin-top: 10px; font-size: .8rem; color: #a9acd6; line-height: 1.55; }
.footer-pay { display: inline-block; margin-top: 6px; font-size: .8rem; color: #a9acd6; line-height: 1.5; }  /* 1.65.1 */
.footer-est a { color: #c9ccec; text-decoration: underline; }
.footer-bottom {
  text-align: center;
  padding: 14px;
  border-top: 1px solid rgba(255, 255, 255, .12);
  font-size: .75rem;
}
/* Calendar toolbar on a phone: the week's visual is an icon. */
/* Table cards on a phone, two facts per row (1.40.0): the label sits above
   its value like a small tile, so a card is half as tall as the old
   label-left, value-right list. The title and the actions keep the width. */
/* The EU flag next to "Hosted in the EU" in the footer (1.40.1). */
.eu-host { white-space: nowrap; }  /* 1.40.0: mobile polish from the September screenshots */
.eu-flag { vertical-align: -2px; border-radius: 2px; margin-right: 2px; }
@media (max-width: 820px) {
  .site-footer { display: none; }  /* Responsive */
}

/* ---------- Consent bar (1.1.14) ---------- */
/* Consent bar (1.1.14) */
.consent-bar {
  position: fixed; left: 12px; right: 12px; bottom: 12px; z-index: 90; max-width: 720px; margin: 0 auto;
  display: flex; flex-wrap: wrap; gap: 8px 14px; align-items: center; justify-content: space-between;
  padding: 12px 16px; background: var(--card); color: var(--ink); border: 1px solid var(--border); border-radius: var(--r-md); box-shadow: var(--shadow-lg);
  font-size: .85rem; line-height: 1.4;
}
.consent-bar p { margin: 0; flex: 1 1 320px; }
.consent-actions { display: flex; gap: 8px; }
.consent-state { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
@media (max-width: 820px) {
  .consent-bar { bottom: calc(64px + env(safe-area-inset-bottom)); }
}

/* ---------- Navigation progress bar (v1.1.6) ---------- */
/* Slim navigation progress bar under the header (in-app loads) */
#nav-progress { position: fixed; left: 0; top: var(--hdr, 0px); height: 3px; width: 100%; transform: scaleX(0); transform-origin: left; /* 1.69.5: scaled, not resized: no layout per frame */ background: var(--esn-cyan); z-index: 60; opacity: 0; pointer-events: none; transition: width .35s ease, opacity var(--t-slow) ease; }
#nav-progress.on { opacity: 1; transform: scaleX(.7); transition: transform 1.6s cubic-bezier(.2,.7,.3,1), opacity .1s; }
#nav-progress.on.done { transform: scaleX(1); opacity: 0; transition: transform .25s ease, opacity .35s ease .15s; }

/* ---------- Icon button in the header (v1.1.6) ---------- */
.icon-btn { background: none; border: 0; color: #fff; cursor: pointer; width: 38px; height: 38px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; opacity: .85; }
.icon-btn:hover { background: rgba(255, 255, 255, .12); opacity: 1; }
.icon-btn .material-symbols-rounded { font-size: 20px; }
@media (max-width: 820px) {
  .icon-btn.d-only { display: none !important; }
}

/* ============================================================
   COMPONENTS: buttons, chips, badges, cards, forms, tables, menus,
   dialogs, toasts, charts
   ============================================================ */

/* ---------- Buttons ---------- */
/* Links styled as buttons: the generic dark-mode link color (cyan) must
   never override button text colors — cyan-on-cyan made buttons vanish. */
html[data-theme="dark"] a.btn { color: #fff; }
html[data-theme="dark"] a.btn-ghost, html[data-theme="dark"] a.btn.btn-ink { color: var(--ink); }
.btn-ink { color: var(--esn-dark); }
html[data-theme="dark"] .btn-ink { color: var(--ink); }
.btn .material-symbols-rounded { font-size: 16px; vertical-align: 0; line-height: 1; }
.btn-sm .material-symbols-rounded { font-size: 16px; vertical-align: 0; line-height: 1; }
.btn {
  border: none;
  padding: 9px 18px;
  font-family: inherit;
  font-weight: 700;
  font-size: .9rem;
  cursor: pointer;
  text-align: center;
  border-radius: 9px;
  touch-action: manipulation;
  -webkit-user-select: none;
  user-select: none;
  transition: transform .08s ease, filter .15s ease, background-color .15s ease, border-color .15s ease;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  min-height: 40px;
  line-height: 1.15;
  vertical-align: middle;
}
.btn:hover { text-decoration: none; filter: brightness(.96); transform: translateY(-1px); box-shadow: 0 3px 10px rgba(25, 26, 46, .12); }
.btn:disabled { opacity: .55; cursor: not-allowed; }
html[data-theme="dark"] .btn:disabled { opacity: .4; }
/* Buttons and badges on the bright brand colours take ink; magenta and
   the dark blue keep white. */
.btn-cyan { background: var(--esn-cyan); color: var(--on-bright); }
.btn-magenta { background: #d10078; color: #fff; }  /* 1.55.0: a deeper magenta, 5.3:1 with white (was 4.25) */
.btn-green { background: var(--esn-green); color: var(--on-bright); }
.btn-orange { background: var(--esn-orange); color: var(--on-bright); }
.btn-dark { background: var(--esn-dark); color: #fff; }
/* Buttons: dark-blue on near-black is unreadable — swap to a lighter indigo,
   and hovers should brighten (not darken) on dark surfaces. */
html[data-theme="dark"] .btn-dark { background: #4d54d8; }
.btn-ghost { background: transparent; color: inherit; border: 1px solid var(--border); }
html[data-theme="dark"] .btn-ghost { color: var(--ink); border-color: #3a3d6b; }
.btn-ghost:hover { background: var(--hover); transform: none; box-shadow: none; }
html[data-theme="dark"] .btn-ghost:hover { background: var(--surface2); }
/* Icon-only small buttons get a proper hit area */
.btn-sm { font-size: .8rem; min-width: 36px; min-height: 34px; padding: 6px 12px; gap: 5px; }
label.btn { cursor: pointer; }  /* 1.1.37: Profile picture card */
label.btn.is-disabled { opacity: .55; pointer-events: none; }
.btn:active { box-shadow: none; }  /* v1.10: Premium polish pass */
html[data-theme="dark"] .btn:hover { filter: brightness(1.08); }
.btn .btn-spin, .btn-spin {
  display: inline-block; width: 1em; height: 1em; vertical-align: -2px;
  border: 2px solid rgba(255, 255, 255, .35); border-top-color: #fff;
  border-radius: 50%; animation: spin .7s linear infinite; margin-right: 2px;
}  /* v0.139: Button busy spinner */
.btn-ghost .btn-spin, .btn-ink .btn-spin { border-color: rgba(128, 128, 160, .3); border-top-color: currentColor; }
/* 1.78.7: booking a ticket: a ticket being printed (or the checkout lock) and a light sweep, not a spinner; then a short "You're in!" */
.btn.is-ticket { position: relative; overflow: hidden; }
.btn.is-ticket::after { content: ""; position: absolute; inset: 0; background: linear-gradient(100deg, transparent 20%, rgba(255, 255, 255, .3) 50%, transparent 80%); transform: translateX(-100%); pointer-events: none; }
.btn-tk { display: inline-flex; }
.btn.is-done, html .btn.is-done:disabled { background: var(--esn-green); border-color: var(--esn-green); color: var(--on-bright); opacity: 1; }
html .btn.is-ticket:disabled { opacity: 1; cursor: progress; }  /* working on your ticket, not unavailable (the dark disabled rule dimmed it to .4) */
@keyframes tk-print { 0%, 100% { transform: translateY(-2px) rotate(-10deg); } 50% { transform: translateY(2px) rotate(6deg); } }
@keyframes tk-sweep { to { transform: translateX(100%); } }
@keyframes tk-done { 0% { transform: scale(.5); } 60% { transform: scale(1.25); } 100% { transform: scale(1); } }
@media (prefers-reduced-motion: no-preference) {
  .btn.is-ticket::after { animation: tk-sweep 1.3s ease-in-out infinite; }
  .btn-tk .material-symbols-rounded { animation: tk-print 1s ease-in-out infinite; }
  .btn.is-done .material-symbols-rounded { animation: tk-done .45s cubic-bezier(.2, .7, .3, 1.5) both; }
}
.btn.is-busy { opacity: .85; cursor: progress; }
/* v1.4.0: Colour language. The !important stays: the codex delete button (app.js) still carries color: var(--esn-magenta) inline. */
.btn.btn-danger { color: var(--danger) !important; border-color: var(--danger) !important; background: transparent; }
.btn.btn-danger:hover:not(:disabled) { background: var(--danger-soft); }
.btn.btn-danger-solid { background: var(--danger); color: #fff; border-color: var(--danger); }
.btn.btn-danger-solid:hover:not(:disabled) { filter: brightness(0.92); }
.btn:active:not(:disabled) { transform: scale(.97); }  /* Calm everywhere else */
.btn-block { display: flex; width: 100%; }  /* 1.14.1: one button */
/* The icon-only button (1.29.1, 34px since 1.29.4); .btn-icon is the same thing by its older name. */
.btn.btn-ico, .btn.btn-icon { width: 34px; height: 34px; min-width: 34px; min-height: 34px; padding: 0; justify-content: center; gap: 0; }
.btn.btn-ico .material-symbols-rounded, .btn.btn-icon .material-symbols-rounded { font-size: 16px; }
.btn-ico, .btn-icon { min-width: 34px; min-height: 34px; }  /* 1.29.4: one system */
/* Link buttons on the bright fills also take ink (a.btn rules set white) */
a.btn-cyan, a.btn-green, a.btn-orange, a.btn-cyan:hover, a.btn-green:hover, a.btn-orange:hover { color: var(--on-bright); }  /* 1.29.4: colour follow-ups */
html[data-theme="dark"] a.btn-cyan, html[data-theme="dark"] a.btn-green, html[data-theme="dark"] a.btn-orange { color: var(--on-bright); }

/* ---------- Search & filter bar ---------- */
.filter-bar { display: flex; flex-direction: row; flex-wrap: wrap; gap: 8px; margin: 0 0 12px; align-items: center; }
.filter-bar input[type="search"] {
  border-radius: var(--r-sm);
  border: 1px solid var(--border);
  font-family: inherit;
  background: var(--card);
  color: var(--ink);
  outline: none;
  flex: 1 1 200px;
  max-width: 340px;
  min-width: 0;
  height: 36px;
  padding: 0 12px 0 34px;
  font-size: .9rem;
  box-shadow: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%238a8db0' stroke-width='2.2' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='m20 20-3.5-3.5'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: 11px 50%;
  background-size: 16px;
}
.filter-bar input[type="search"]:focus { border-color: var(--accent-text); }  /* 1.55.0: contrast */
.filter-chips { display: flex; gap: 8px; flex-wrap: wrap; }
.chip {
  border: 1px solid var(--border);
  background: var(--card);
  padding: 9px 14px;
  border-radius: var(--r-sm);
  font-family: inherit;
  font-weight: 700;
  font-size: .8rem;
  cursor: pointer;
  color: var(--muted);
  touch-action: manipulation;
  -webkit-user-select: none;
  user-select: none;
  transition: transform .08s ease;
}
.chip:hover { border-color: #c9ccdc; color: var(--ink); }
.chip.active { background: var(--esn-dark); border-color: var(--esn-dark); color: #fff; }
html[data-theme="dark"] .chip.active { background: var(--esn-cyan); border-color: var(--esn-cyan); color: #0d0e22; }
.globe-toggle { font-size: .85rem; margin-left: 2px; }  /* 1.12.0: The globe */
.chip.chip-static { cursor: default; padding: 2px 9px; font-size: .75rem; }  /* 1.1.20: Board space */
.chip.chip-static b { margin-left: 2px; }
.chip.chip-static.muted { color: var(--muted); border-style: dashed; }  /* 1.78.4: was opacity .65 */
.filter-selects { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: -4px 0 12px; }  /* v1.3.0: Users tab */
.fsel { display: flex; font-weight: 700; text-transform: uppercase; letter-spacing: .5px; color: var(--muted); flex-direction: row; align-items: center; gap: 6px; padding-left: 10px; border: 1px solid var(--border); border-radius: var(--r-sm); background: var(--card); font-size: .75rem; }
.fsel select { font: inherit; font-weight: 500; text-transform: none; letter-spacing: 0; font-size: .85rem; color: var(--ink); border-radius: var(--r-sm); border: 0; background: transparent; padding: 7px 26px 7px 2px; max-width: 200px; }
#shift-view-chips .chip b {
  background: rgba(0, 0, 0, .14);
  border-radius: 10px;
  padding: 0 5px;
  margin-left: 4px;
  font-size: .8rem;
}  /* 1.1.33: Shiftlists */
#shift-view-chips .chip.active b { background: rgba(255, 255, 255, .25); }
.chip:active { transform: scale(.96); }  /* Calm everywhere else */
/* The team pages' search bar is one row: the field, the count, the buttons. */
.filter-bar.row { flex-direction: row; flex-wrap: wrap; align-items: center; gap: 8px 10px; }  /* 1.15.0: colours per category */
.filter-bar.row input[type="search"] { flex: 1 1 240px; max-width: 440px; min-width: 0; }
.filter-bar.row > .form-hint { white-space: nowrap; }
.filter-bar.row .ev-year-pick { margin-left: auto; }  /* 1.18.0: admin dashboard */
.filter-bar > .form-hint { white-space: nowrap; font-size: .8rem; }  /* 1.27.0: one whole */
.filter-bar + .filter-selects { margin-top: -4px; }
.fsel select:focus { outline: none; box-shadow: none; }
.fsel:focus-within { border-color: var(--esn-cyan); box-shadow: var(--ring-soft); }  /* the ring sits on the wrapper, the select inside has no border */
.filter-bar .fsel { margin: 0; }
.filter-pop { position: relative; }  /* 1.27.1: filters behind one button */
.filter-pop > summary { cursor: pointer; }
.filter-pop.is-set > summary { border-color: var(--esn-cyan); color: var(--esn-dark); }
.filter-pop-n { display: inline-flex; align-items: center; justify-content: center; min-width: 18px; height: 18px; padding: 0 5px; border-radius: 9px; background: var(--esn-cyan); color: var(--on-bright); font-size: .7rem; font-weight: 800; margin-left: 2px; }
.filter-pop-body { position: absolute; top: calc(100% + 6px); left: 0; z-index: 40; max-width: min(92vw, 420px); background: var(--card); border: 1px solid var(--border); border-radius: var(--r-md); box-shadow: var(--shadow-pop); padding: 10px; min-width: 280px; }
.filter-pop-body .filter-selects { margin: 0; flex-direction: column; align-items: stretch; gap: 8px; }
.filter-pop-body .fsel { justify-content: space-between; height: 38px; }
.filter-pop-body .fsel select { max-width: 60%; }
th.num, td.num { text-align: right; font-variant-numeric: tabular-nums; }
.filter-bar > .filter-chips, .filter-bar > .chips {
  flex: 0 1 auto; min-width: 0; display: inline-flex; flex-wrap: nowrap; gap: 2px; padding: 3px; margin: 0;
  background: var(--surface2); border: 1px solid var(--border); border-radius: 10px; overflow-x: auto; scrollbar-width: none;
}  /* 1.28.0: the toolbar */
.filter-bar > .filter-chips::-webkit-scrollbar { display: none; }
.filter-bar > .filter-chips .chip {
  border: 0; background: transparent; box-shadow: none; padding: 6px 10px; border-radius: 7px; font-size: .8rem; font-weight: 700; color: var(--muted); white-space: nowrap; min-height: 30px; display: inline-flex; align-items: center; gap: 5px;
}
.filter-bar > .filter-chips .chip .material-symbols-rounded { font-size: 16px; }
.filter-bar > .filter-chips .chip:hover { background: var(--hover); color: var(--ink); }
.filter-bar > .filter-chips .chip.active { background: var(--card); color: var(--ink); box-shadow: 0 1px 2px rgba(16, 18, 60, .14); }
html[data-theme="dark"] .filter-bar > .filter-chips .chip.active { background: #2f3266; color: #fff; box-shadow: none; }
html[data-theme="dark"] .filter-bar > .filter-chips .chip:hover { background: #2a2d5a; color: #fff; }
.filter-bar .fsel, .filter-selects .fsel { height: 36px; font-size: .75rem; }
.filter-bar .fsel select, .filter-selects .fsel select { padding: 0 24px 0 4px; height: 34px; font-size: .85rem; }
.filter-bar .filter-pop > summary, .filter-bar .more-menu > summary { min-height: 36px; padding: 0 10px; font-size: .8rem; }
.filter-bar .ev-year-pick, .filter-bar .tb-right { margin-left: auto; display: inline-flex; align-items: center; gap: 8px; }
.filter-bar .ev-year-pick select { width: auto; min-width: 150px; height: 36px; border-radius: var(--r-sm); border: 1px solid var(--border); background: var(--card); color: var(--ink); font: inherit; font-size: .85rem; padding: 0 26px 0 8px; }
.filter-pop-body .filter-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.filter-pop-body .btn { width: 100%; justify-content: center; }
@media (max-width: 820px) {
  /* An inline style on the element beats this margin, so any chip row that
     sets its own margin kept the padding and lost the negative bleed: the
     strip started 24px in and its last tab sat under the fade. Subnavs now
     use .subnav-chips instead of an inline margin (1.1.46). */
  .filter-chips { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none;
    -webkit-mask-image: linear-gradient(90deg, #000 calc(100% - 32px), transparent); mask-image: linear-gradient(90deg, #000 calc(100% - 32px), transparent); padding: 2px 36px 6px 16px; margin: 0 -16px; }  /* Responsive */
  .filter-chips::-webkit-scrollbar { display: none; }
  .chip { flex: none; }
}
@media (max-width: 640px) {
  .fsel { flex: 1 1 45%; }  /* v1.3.0: Users tab */
  .fsel select { width: 100%; }
  .filter-bar.row input[type="search"] { flex-basis: 100%; }  /* 1.15.0: colours per category */
  .filter-bar.row > .btn[style*="margin-left:auto"] { margin-left: 0 !important; }
  .filter-pop-body { position: fixed; left: 16px; right: 16px; top: auto; bottom: calc(var(--bottom-nav, 64px) + 12px); max-width: none; }  /* 1.27.1: filters behind one button */
  .filter-bar input[type="search"] { flex-basis: 100%; max-width: none; }  /* 1.28.0: the toolbar */
  .filter-bar > .filter-chips { flex: 0 0 auto; max-width: 100%; }
  .filter-bar .ev-year-pick, .filter-bar .tb-right { margin-left: 0; }
}

/* ---------- Event cards ---------- */
.events-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(310px, 100%), 1fr));
  gap: 20px;
  margin-bottom: 44px;
}
/* "Last spots!" corner ribbon on event cards (<10% capacity left) */
/* Long lists: cards below the fold skip layout until they scroll near */
.event-card {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  border-top: 4px solid var(--accent, var(--esn-cyan));
  transition: box-shadow .15s ease;
  position: relative;
  content-visibility: auto;
  contain-intrinsic-size: auto 380px;
}
.event-card:hover { box-shadow: var(--shadow-lg); }
/* 1.48.0: one anatomy for every card - a 2:1 media area (photo, or the
   category colour with its icon), the date stamp in its bottom-left corner. */
.card-media { position: relative; aspect-ratio: 2 / 1; overflow: hidden; flex: none; background: color-mix(in srgb, var(--accent, var(--esn-cyan)) 16%, var(--card)); }
.card-img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform .45s cubic-bezier(.2, .6, .2, 1); }
/* 1.69.5: pictures fade in over their tinted placeholder (html.img-fade comes from ux.js) */
.img-fade .card-img:not(.ld), .img-fade :is(.hnews-img, .agenda-pic) img:not(.ld) { opacity: 0; }
.img-fade .card-img.ld { transition: opacity .35s ease, transform .45s cubic-bezier(.2, .6, .2, 1); }  /* only on the way in */
.img-fade :is(.hnews-img, .agenda-pic) img.ld { transition: opacity .35s ease; }
/* 1.69.5: the search match in a card title */
.card-link mark { background: color-mix(in srgb, var(--esn-cyan) 32%, transparent); color: inherit; border-radius: 3px; padding: 0 1px; }
.home-empty .btn { margin-left: 6px; }
.card-ph {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  background: radial-gradient(120% 140% at 85% 0%, color-mix(in srgb, var(--accent, var(--esn-cyan)) 42%, var(--card)), color-mix(in srgb, var(--accent, var(--esn-cyan)) 12%, var(--card)) 70%);
  color: color-mix(in srgb, var(--accent, var(--esn-cyan)) 78%, var(--ink));
}
.card-ph .material-symbols-rounded { font-size: 64px; opacity: .9; }
.event-card .card-body { padding: 14px 18px 14px; display: flex; flex-direction: column; gap: 6px; flex: 1; min-width: 0; }
.event-card h3, .event-card h4 { font-size: 1.05rem; font-weight: 900; line-height: 1.3; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; overflow-wrap: anywhere; }
.event-card h3 a, .event-card h4 a { color: var(--ink); }
/* The title link covers the card: one tap target, one name for screen readers. */
.card-link::after { content: ""; position: absolute; inset: 0; z-index: 1; }
.card-link:hover { text-decoration: none; }
.card-link:focus-visible { outline: none; }
.event-card:has(.card-link:focus-visible) { outline: var(--ring); outline-offset: 2px; box-shadow: var(--ring-gap), var(--shadow-lg); }
.event-card .card-act { position: relative; z-index: 2; }
/* At most two quiet category labels: a dot in the tag colour, sentence case. */
.ev-tags { display: flex; gap: 6px; min-width: 0; overflow: hidden; }
.ev-tag {
  display: inline-block; min-width: 0; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  padding: 2px 9px 2px 8px; border-radius: 999px; font-size: .75rem; font-weight: 600; color: var(--ink); line-height: 1.5;
  background: color-mix(in srgb, var(--tc, var(--accent)) 13%, transparent);
}
.ev-tag::before { content: ""; display: inline-block; width: 7px; height: 7px; border-radius: 50%; background: var(--tc, var(--accent)); margin-right: 6px; vertical-align: 1px; }
.ev-tag.more { flex: none; color: var(--muted); background: var(--surface2); }
.ev-tag.more::before { content: none; }
.event-meta {
  font-size: .8rem;
  color: var(--muted);
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.event-meta .ev-where { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.event-desc { font-size: .85rem; line-height: 1.45; color: var(--muted); display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; overflow-wrap: anywhere; }
/* Price on the left, one status on the right, never truncated. */
.card-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-top: auto;
  padding-top: 10px;
  border-top: 1px solid var(--border);
}
.card-foot > .price-tag { flex-direction: column; align-items: flex-start; gap: 0; min-width: 0; line-height: 1.25; }
.card-foot > :last-child:not(:first-child) { margin-left: auto; flex: none; }
.card-status { display: inline-flex; align-items: center; gap: 4px; font-size: .8rem; font-weight: 800; color: var(--muted); white-space: nowrap; }
.card-status.st-live { color: var(--green-text); }
.card-status.st-live .material-symbols-rounded { animation: livePulse 1.6s ease-in-out infinite; }
.card-status.st-few { color: var(--orange-text); }
.card-status.st-off { color: var(--danger); }
.card-status.st-link { color: var(--accent-text); }
/* Accent-coloured surfaces carry --on-accent (set by the page from the
   accent's own luminance), so a cyan or green card is never white-on-cyan. */
.date-badge {
  position: absolute;
  left: 12px;
  bottom: 12px;
  z-index: 1;
  min-width: 48px;
  background: var(--accent, var(--esn-cyan));
  border-radius: var(--r-sm);
  padding: 5px 10px;
  text-align: center;
  font-weight: 900;
  line-height: 1.15;
  color: var(--on-accent, #fff);
  box-shadow: 0 2px 8px rgba(18, 20, 42, .28);
}
.date-badge .d { font-size: 1.3rem; display: block; }
.date-badge .m { font-size: .7rem; text-transform: uppercase; letter-spacing: 1.5px; }
.price-tag { font-weight: 900; color: var(--esn-dark); font-size: 1rem; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-variant-numeric: tabular-nums; }
html[data-theme="dark"] .price-tag { color: var(--esn-cyan); }
.price-strike { text-decoration: line-through; color: var(--muted); font-size: .85em; font-weight: 700; }  /* 1.77.0: muted ink instead of half opacity (2.7:1) */
.member-note { font-size: .8rem; color: var(--accent-text); font-weight: 700; }
/* Goodie bag line (1.1.10) - wherever the card pickup is mentioned. */
.goodie-note { display: flex; gap: 8px; align-items: flex-start; margin: 10px 0 0; padding: 10px 12px; border-radius: 10px;
  background: color-mix(in srgb, var(--esn-green) 14%, var(--card)); border: 1px solid color-mix(in srgb, var(--esn-green) 45%, var(--border));
  font-size: .9rem; line-height: 1.4; color: var(--ink); }
.goodie-note .material-symbols-rounded { color: var(--esn-green); flex: none; margin-top: 1px; }
.goodie-note.compact { padding: 7px 10px; font-size: .85rem; margin: 6px 0 10px; }
/* Cards inside grids stagger in a touch later. 1.69.1: on arriving only
   (like the page itself): a chip tap or a search re-renders the grid, and
   every card used to blink in again. */
#app[data-enter] .events-grid > * { animation: settleIn .32s ease backwards; }
.events-grid > *:nth-child(2) { animation-delay: .05s; }
.events-grid > *:nth-child(3) { animation-delay: .1s; }
.events-grid > *:nth-child(4) { animation-delay: .14s; }
.events-grid > *:nth-child(n+5) { animation-delay: .18s; }
.event-meta .material-symbols-rounded.mi-sm { vertical-align: -3px; opacity: .75; }  /* v0.125 */
/* A sold-out card should read as past its moment without being unreadable. */
.event-card:has(.ribbon-out) :is(.card-img, .card-ph), .event-card:has(.ribbon-off) :is(.card-img, .card-ph) {
  filter: grayscale(.55) brightness(.92);
}
.card-media > .ev-ico {
  position: absolute;
  top: 12px;
  left: 12px;
  z-index: 2;
  width: 38px;
  height: 38px;
  border-radius: var(--r-md);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  /* 1.58.0: dark glass, so a white icon reads on a light picture too; the category colour as an underline */
  background: rgba(18, 20, 56, .78);  /* 1.69.0: no backdrop blur - twenty blurred layers repainted on every scroll of the home page */
  border: 1px solid rgba(255, 255, 255, .28);
  box-shadow: inset 0 -3px 0 var(--c, var(--esn-cyan)), 0 3px 10px rgba(29, 31, 49, .35);
}  /* 1.1.33: Event icons */
.card-media > .ev-ico .material-symbols-rounded { font-size: 20px; }
/* v0.130: text-on-card green needs a darker ink for contrast (the
   brand green stays on fills/badges). */
.price-tag.free { color: var(--green-text); }  /* 1.29.4: one system */
html[data-theme="dark"] .price-tag.free { color: var(--green-text); }  /* the dark .price-tag rule would paint it cyan */
@media (max-width: 820px) {
  /* Compact event cards */
  .events-grid { grid-template-columns: minmax(0, 1fr); gap: 12px; margin-bottom: 30px; }  /* Responsive */
  .card-media { aspect-ratio: 5 / 2; }
  .event-card .card-body { padding: 12px 16px 12px; gap: 5px; }
  .event-card h3, .event-card h4 { font-size: 1rem; }
  .date-badge { left: 10px; bottom: 10px; padding: 4px 9px; }
  .date-badge .d { font-size: 1.15rem; }
}
@media (hover: hover) {
  .event-card { transition: box-shadow .2s ease, transform .2s ease; }
  .event-card:hover { transform: translateY(-3px); box-shadow: var(--shadow-lg); }
  .event-card:hover .card-img { transform: scale(1.045); }
}

/* ---------- Badges ---------- */
/* Status badges stay on one line. */
/* Badges never widen a card. */
.badge {
  display: inline-block;
  padding: 2px 9px;
  border-radius: 6px;
  font-size: .7rem;
  font-weight: 700;
  letter-spacing: .4px;
  text-transform: uppercase;
  color: #fff;
  background: var(--grey-fill, #6b6e8a);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  vertical-align: bottom;
}
.badge-paid { background: var(--esn-green); color: var(--on-bright); }
.badge-pending { background: var(--esn-orange); color: var(--on-bright); }
.badge-free { background: var(--esn-cyan); color: var(--on-bright); }
.badge-published { background: var(--esn-green); color: var(--on-bright); }
.badge-esn { background: var(--esn-dark); }
html[data-theme="dark"] .badge-esn { background: #4d54d8; }
.badge-verified { background: var(--esn-green); color: var(--on-bright); }
.badge-requested { background: var(--esn-orange); color: var(--on-bright); }
.badge-failed { background: var(--danger); }
.badge-live {
  background: var(--esn-green);
  color: var(--on-bright);  /* 1.55.0: white on green was 2.2:1 */
  animation: livePulse 1.6s ease-in-out infinite;
}  /* v0.99.7: "Happening now" badge */
.badge-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: 10px; }  /* Passport cover (v0.108 redesign) */
/* Queue: cyan = "to pick up", orange stays "money" */
.badge-cyan { background: var(--esn-cyan); color: var(--on-bright); }
.badge .material-symbols-rounded { vertical-align: -3px; }  /* 1.15.0: colours per category */
/* Settings: badge artwork. */
.badge-art-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 8px; }  /* 1.33.0: friends going */
.badge-art-row { display: flex; align-items: center; gap: 8px; padding: 6px 8px; border: 1px solid var(--border); border-radius: 10px; }
.badge-art-prev { width: 40px; height: 40px; border-radius: 10px; background: var(--hover); display: flex; align-items: center; justify-content: center; flex: none; }
.badge-art-prev img { width: 34px; height: 34px; object-fit: contain; }
.badge-art-name { flex: 1; font-size: .8rem; text-transform: capitalize; }
.badge-soldout { background: var(--grey-fill); }  /* 1.29.4: one system */
.badge-draft { background: var(--grey-fill); }
.badge-refunded { background: var(--grey-fill); }
.badge-cancelled { background: var(--grey-fill); }
html[data-theme="dark"] .badge-failed { background: #d92b41; }

/* ---------- Settings markers (1.1.15) ---------- */
.tag-row.dirty, .venue-row.dirty { outline: 2px dashed var(--esn-orange); outline-offset: 2px; border-radius: 10px; }
.unsaved-badge { margin-left: 8px; }
.settings-tabs .dirty-dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; background: var(--esn-orange); margin-left: 6px; vertical-align: middle; }
.venue-ph { width: 64px; height: 36px; border-radius: 6px; background: var(--bg); border: 1px dashed var(--border); display: inline-flex; align-items: center; justify-content: center; color: var(--muted); flex: none; }
.bn-preview { position: static; margin-top: 10px; border-radius: 10px; }
.linklike { background: none; border: 0; padding: 0; cursor: pointer; font: inherit; text-decoration: underline; color: var(--accent-text); min-height: 30px; display: inline-flex; align-items: center; }
.body-picks { display: flex; flex-direction: column; gap: 2px; }
tr.row-muted td { opacity: .72; }
.chart-empty { display: flex; align-items: center; justify-content: center; min-height: 120px; border: 1px dashed var(--border); border-radius: 10px; margin-top: 6px; }
.chart-data { margin-top: 4px; }
/* 1.78.7: a "show the numbers" table fits its box at any width: fixed columns, headers that wrap, no sideways scroll */
.chart-data table { table-layout: fixed; }
.chart-data th, .chart-data td { white-space: normal; overflow-wrap: anywhere; padding-left: 6px; padding-right: 6px; }
.chart-data th:first-child, .chart-data td:first-child { width: 22%; }
@media (max-width: 640px) { .chart-data th, .chart-data td { padding: 5px 3px; font-size: .7rem; letter-spacing: 0; } }
.news-preview { border: 1px dashed var(--border); border-radius: var(--r-md); padding: 12px; margin-top: 10px; }
#kiosk-exit.holding { background: var(--esn-orange); color: var(--on-bright); transition: background .1s linear; }
#scan-queue { display: block; max-width: 420px; text-align: center; }
.linklike:hover { color: var(--esn-cyan); }  /* 1.29.4: one system */

/* ---------- Hints: the info icon ---------- */
/* Small info icon that replaces verbose form hints (hover title / tap toast) */
/* Tap targets: nothing you can tap is under 30px tall */
.hint-i {
  border: none;
  background: none;
  cursor: help;
  color: var(--muted);
  vertical-align: middle;
  min-width: 30px;
  min-height: 30px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin: -8px 0;
  padding: 0 4px;
}
.hint-i:hover { color: var(--esn-cyan); }
.hint-i .material-symbols-rounded { font-size: 14px; vertical-align: -3px; }
/* Highlight rows that need action (e.g. paid ESNcard applications to assign) */
.row-hot td { background: rgba(122, 193, 67, 0.10); }
html[data-theme="dark"] .row-hot td { background: rgba(122, 193, 67, 0.12); }
.title-help { display: inline-flex; vertical-align: middle; margin-left: 2px; }  /* 1.27.0: one whole */
.fold-help { margin: -6px 0 14px; }
.fold-help summary { color: var(--muted); font-size: .8rem; }
.fold-help summary .material-symbols-rounded { font-size: 16px; }
.fold-help[open] > p.form-hint { margin: 8px 0 0; max-width: 78ch; }
.title-help .hint-i { padding: 0 4px; }  /* 1.29.4: one system */

/* ---------- Stars (event feedback) ---------- */
.star-row { display: flex; justify-content: center; gap: 6px; margin-top: 14px; }
.star {
  border: none;
  background: none;
  font-size: 2.4rem;
  line-height: 1;
  cursor: pointer;
  color: var(--border);
  padding: 2px;
}
.star.on { color: var(--esn-orange); }
.star-row .star { min-width: 34px; min-height: 34px; display: inline-flex; align-items: center; justify-content: center; }  /* 1.29.4: one system */

/* ---------- Charts (analytics) ---------- */
.chart { display: block; width: 100%; height: auto; margin-top: 4px; }

/* ---------- Insights motion (1.12.0) ---------- */
.kpi-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 10px; margin: 0 0 14px; }
/* One card radius everywhere */
.kpi { position: relative; background: var(--card); border: 1px solid var(--border); padding: 14px 14px 12px; display: flex; flex-direction: column; gap: 2px; min-height: 96px; overflow: hidden; border-radius: var(--radius); }
.kpi-i { color: var(--esn-cyan); line-height: 1; }
.kpi-i .material-symbols-rounded { font-size: 20px; }
.kpi-n { font-size: 1.7rem; font-weight: 900; letter-spacing: -.02em; line-height: 1.1; color: var(--ink); font-variant-numeric: tabular-nums; }
.kpi-l { font-size: .8rem; font-weight: 700; color: var(--ink); }
.kpi-h { font-size: .75rem; color: var(--muted); }
.an-nav { position: sticky; top: var(--hdr, 0px); z-index: 4; display: flex; gap: 2px; align-items: center; overflow-x: auto; scrollbar-width: none; background: var(--bg); padding: 6px 0; margin: 0 0 8px; border-bottom: 1px solid var(--border); }  /* 1.67.3: a slim "on this page" bar, not a second row of chips */
.an-nav::-webkit-scrollbar { display: none; }
.an-nav .an-nav-lbl { flex: none; font-size: .75rem; text-transform: uppercase; letter-spacing: .4px; color: var(--muted); font-weight: 700; margin-right: 8px; }
.an-nav a.chip { flex: none; display: inline-flex; align-items: center; gap: 4px; padding: 6px 10px; border: 0; border-radius: 999px; font-size: .8rem; font-weight: 700; color: var(--muted); text-decoration: none; background: transparent; }
.an-nav a.chip:hover { color: var(--ink); background: var(--surface2); }
.an-nav a.chip.active { color: var(--accent-text); background: var(--surface2); }
html[data-theme="dark"] .an-nav a.chip.active { color: #fff; background: #2f3266; }
.an-group { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; margin: 26px 0 10px; padding-top: 18px; border-top: 2px solid var(--border); font-size: 1.05rem; scroll-margin-top: calc(var(--hdr, 0px) + 44px); }
.an-group small { font-weight: 400; }
.an-group:first-of-type { border-top: 0; padding-top: 0; margin-top: 8px; }
.an-section:not([id]) { scroll-margin-top: calc(var(--hdr, 0px) + 56px); }
/* with an id, [id] (72px, v0.131, later) won */
.an-section > .form-card { margin-bottom: 16px; }
.kpi[data-viz-tip] { cursor: default; outline: none; }  /* 1.13.0: Viz */
.kpi:focus-visible { box-shadow: 0 0 0 2px var(--esn-cyan); }
@media (min-width: 900px) {
  .kpi-grid.four { grid-template-columns: repeat(4, 1fr); }
}
@media (prefers-reduced-motion: no-preference) {
  .an-section.an-armed, .kpi-grid.an-motion.an-armed .kpi { opacity: 0; transform: translateY(10px); transition: opacity .45s ease, transform .45s cubic-bezier(.2, .8, .2, 1); }
  .an-section.an-armed.in, .kpi-grid.an-motion.an-armed.in .kpi { opacity: 1; transform: none; }
  .kpi-grid.an-armed.in .kpi:nth-child(2) { transition-delay: .06s; }
  .kpi-grid.an-armed.in .kpi:nth-child(3) { transition-delay: .12s; }
  .kpi-grid.an-armed.in .kpi:nth-child(4) { transition-delay: .18s; }
  .kpi-grid.an-armed.in .kpi:nth-child(5) { transition-delay: .24s; }
  .an-section.an-armed .bar-cell > div { transform: scaleX(0); transform-origin: left; transition: transform .8s cubic-bezier(.2, .8, .2, 1) .1s; }
  .an-section.an-armed.in .bar-cell > div { transform: none; }
  .an-section.an-armed.still, .kpi-grid.an-armed.still .kpi { opacity: 1; transform: none; transition: none; }
  .an-section.an-armed .viz-cols path.bar { transform-box: fill-box; transform-origin: bottom; transform: scaleY(0); }  /* 1.13.0: Viz */
  .an-section.an-armed.in .viz-cols.animate path.bar, .an-section.an-armed.in .viz-cols path.bar { animation: bar-grow .7s cubic-bezier(.2, .8, .2, 1) forwards; animation-delay: calc(var(--i, 0) * 35ms); }
  .an-section.an-armed .viz-line .line { stroke-dasharray: 1; stroke-dashoffset: 1; }
  .an-section.an-armed.in .viz-line .line { animation: line-draw 1.1s cubic-bezier(.2, .8, .2, 1) forwards; }
  .an-section.an-armed .viz-line .area, .an-section.an-armed .viz-line .end { opacity: 0; transition: opacity .5s ease .9s; }
  .an-section.an-armed.in .viz-line .area { opacity: .1; }
  .an-section.an-armed.in .viz-line .end { opacity: 1; }
  .an-section.an-armed .viz-dots .dot { transform-box: fill-box; transform-origin: center; transform: scale(0); transition: transform .5s cubic-bezier(.2, .8, .2, 1) .2s; }
  .an-section.an-armed.in .viz-dots .dot { transform: none; }
  /* a section marked .still (already shown once) skips the entrance */
  .an-section.an-armed.still .viz-cols path.bar { transform: none; animation: none; transition: none; }
  .an-section.an-armed.still .viz-dots .dot { transform: none; animation: none; transition: none; }
  .an-section.an-armed.still .viz-line .line { stroke-dasharray: none; stroke-dashoffset: 0; animation: none; }
  .an-section.an-armed.still .viz-line .area { opacity: .1; }
  .an-section.an-armed.still .viz-line .end { opacity: 1; }
}

/* ---------- Viz (1.13.0): one chart layer, both themes ---------- */
.viz-tip { position: fixed; z-index: 70; max-width: 260px; padding: 6px 9px; border-radius: var(--r-sm); background: var(--ink); color: var(--card); font-size: .8rem; line-height: 1.4; white-space: pre-line; pointer-events: none; box-shadow: 0 6px 20px rgba(0, 0, 0, .2); }
.viz-tip.hidden { display: none; }
html[data-theme="dark"] .viz-tip { background: #f2f3f8; color: #12132a; }
/* The ring (1.37.0): the chart beside its legend, stacked on a phone. */
.viz-donut { display: flex; align-items: center; gap: 18px; flex-wrap: wrap; margin-top: 6px; }
.vd-ring { width: 170px; height: 170px; flex: none; }
.vd-ring path { outline: none; transition: opacity .15s; }
.vd-ring:hover path:not(:hover) { opacity: .55; }
.vd-big { font-size: 1.05rem; font-weight: 800; fill: var(--ink); }
.vd-small { font-size: .75rem; fill: var(--muted); }
.vd-legend { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; flex: 1 1 160px; min-width: 0; }
.vd-legend li { display: grid; grid-template-columns: 12px 1fr auto; align-items: center; gap: 2px 8px; font-size: .85rem; color: var(--ink); }
.vd-legend li b { font-weight: 800; }
.vd-legend li small { grid-column: 2 / 4; color: var(--muted); font-size: .75rem; }
.viz-legend { display: flex; flex-wrap: wrap; gap: 6px 14px; margin: 2px 0 6px; font-size: .75rem; color: var(--muted); }
.viz-key { display: inline-flex; align-items: center; gap: 6px; }
.viz-swatch { width: 10px; height: 10px; border-radius: 3px; background: var(--c); display: inline-block; }
/* columns */
.viz-cols .bar { fill: var(--c, var(--viz-1)); }
.viz-cols .bar.dim { fill: var(--viz-gray); }
.viz-cols .slot:hover .bar, .viz-cols .hit:focus-visible ~ .bar { filter: brightness(1.12); }
.viz-cols .hit, .viz-line .hit, .viz-dots .hit { fill: transparent; outline: none; cursor: default; }
.viz-cols .slot:hover .hit, .viz-cols .hit:focus-visible { fill: var(--viz-hit); }
/* line */
.viz-line .area { fill: var(--viz-1); opacity: .1; }
.viz-line .line { fill: none; stroke: var(--viz-1); stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.viz-line .dot { fill: var(--viz-1); stroke: var(--card); stroke-width: 2; opacity: 0; }
.viz-line .pt:hover .dot, .viz-line .hit:focus-visible ~ .dot { opacity: 1; }
.viz-line .end { fill: var(--viz-1); stroke: var(--card); stroke-width: 2; }
.viz-ref { stroke: var(--muted); stroke-width: 1; opacity: .6; }
/* dots */
.viz-dots .dot { fill: var(--viz-1); stroke: var(--card); stroke-width: 2; }
.viz-dots .pt:hover .dot, .viz-dots .hit:focus-visible ~ .dot { r: 6; }
/* horizontal bars */
.viz-bars { display: flex; flex-direction: column; gap: 6px; margin-top: 6px; }
@supports (grid-template-columns: subgrid) {
  .viz-bars { display: grid; grid-template-columns: minmax(90px, 34%) minmax(0, 1fr) auto; column-gap: 10px; }  /* 1.78.7: one value column for every row, so every track ends at the same place */
  .viz-bars > .vb-row { grid-column: 1 / -1; grid-template-columns: subgrid; }
}
.vb-row { display: grid; grid-template-columns: minmax(90px, 34%) 1fr auto; align-items: center; gap: 10px; padding: 2px 4px; border-radius: var(--r-sm); outline: none; }
.vb-row:hover, .vb-row:focus-visible { background: var(--surface2); }
.vb-lbl { font-size: .85rem; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
@media (max-width: 640px) { .vb-lbl { white-space: normal; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; } }  /* 1.78.4: a bar's label wraps on a phone instead of being cut */
.vb-lbl a { color: inherit; }
.vb-track { height: 10px; border-radius: 5px; background: var(--surface2); overflow: hidden; }
.vb-fill { display: block; height: 100%; border-radius: 0 5px 5px 0; background: var(--c, var(--viz-1)); }
.vb-val { font-size: .85rem; font-weight: 800; color: var(--ink); font-variant-numeric: tabular-nums; white-space: nowrap; text-align: right; }
.vb-val small { display: block; font-weight: 600; color: var(--muted); font-size: .75rem; white-space: normal; }
/* funnel */
.viz-funnel { display: flex; flex-direction: column; gap: 6px; margin-top: 6px; }
.vf-row { display: grid; grid-template-columns: minmax(90px, 30%) 1fr auto; align-items: center; gap: 10px; padding: 2px 4px; border-radius: var(--r-sm); outline: none; }
.vf-row:hover, .vf-row:focus-visible { background: var(--surface2); }
.vf-lbl { font-size: .85rem; color: var(--ink); }
.vf-track { height: 14px; border-radius: 7px; background: var(--surface2); overflow: hidden; }
.vf-fill { display: block; height: 100%; border-radius: 0 7px 7px 0; background: var(--viz-s5); }
.vf-fill[style*="--s:2"] { background: var(--viz-s3); }
.vf-fill[style*="--s:4"] { background: var(--viz-s4); }
.vf-fill[style*="--s:6"] { background: var(--viz-s5); }
.vf-fill[style*="--s:7"] { background: var(--viz-s6); }
.vf-val { font-size: .85rem; font-weight: 800; color: var(--ink); font-variant-numeric: tabular-nums; text-align: right; }
.vf-val small { display: block; font-weight: 600; color: var(--muted); font-size: .75rem; }
/* ratings distribution */
.viz-dist { display: flex; flex-direction: column-reverse; gap: 4px; margin-top: 6px; }
.vd-row { display: grid; grid-template-columns: 34px 1fr 34px; align-items: center; gap: 8px; padding: 1px 4px; border-radius: 6px; outline: none; }
.vd-row:hover, .vd-row:focus-visible { background: var(--surface2); }
.vd-lbl { font-size: .8rem; color: var(--muted); }
.vd-track { height: 8px; border-radius: 4px; background: var(--surface2); overflow: hidden; }
.vd-fill { display: block; height: 100%; border-radius: 0 4px 4px 0; background: var(--viz-1); }
.vd-val { font-size: .8rem; font-weight: 800; color: var(--ink); text-align: right; font-variant-numeric: tabular-nums; }
/* heat grid */
.viz-heat { display: grid; grid-template-columns: auto repeat(var(--cols), minmax(0, 1fr)); gap: 3px; margin-top: 8px; font-size: .75rem; }
.vh-corner, .vh-col, .vh-row { color: var(--muted); }
.vh-col { text-align: center; padding-bottom: 2px; }
.vh-row { padding-right: 6px; display: flex; align-items: center; }
.vh-cell { aspect-ratio: 1.6 / 1; border-radius: 5px; background: var(--surface2); display: flex; align-items: center; justify-content: center; outline: none; }
.vh-cell i { font-style: normal; font-weight: 700; font-size: .75rem; color: var(--ink); }
.vh-cell.s5 i, .vh-cell.s6 i, .vh-cell.s7 i { color: #fff; }
html[data-theme="dark"] .vh-cell.s5 i, html[data-theme="dark"] .vh-cell.s6 i, html[data-theme="dark"] .vh-cell.s7 i { color: #12132a; }
.vh-cell.s1 { background: var(--viz-s1); }
.vh-cell.s2 { background: var(--viz-s2); }
.vh-cell.s3 { background: var(--viz-s3); }
.vh-cell.s4 { background: var(--viz-s4); }
.vh-cell.s5 { background: var(--viz-s5); }
.vh-cell.s6 { background: var(--viz-s6); }
.vh-cell.s7 { background: var(--viz-s7); }
.vh-cell:hover, .vh-cell:focus-visible { box-shadow: inset 0 0 0 2px var(--ink); }
/* tiles */
.kpi-delta { display: inline; font-weight: 800; font-size: .75rem; margin-right: 6px; }
.kpi-delta b { white-space: nowrap; font-weight: 800; }
.kpi-delta small { font-weight: 600; color: var(--muted); font-size: .7rem; }
.kpi-delta.bad { color: var(--viz-critical); }
.kpi-delta.flat { color: var(--muted); }
.kpi-spark { position: absolute; right: 10px; top: 12px; width: 84px; height: 26px; opacity: .9; }
.kpi-spark polyline { fill: none; stroke: var(--viz-gray); stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.kpi-spark circle { fill: var(--viz-1); }
.kpi-warn .kpi-i { color: var(--viz-serious); }
.kpi-good .kpi-i { color: var(--viz-good); }
/* dashboard scaffolding */
.dash-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 400px), 1fr)); gap: 14px; margin-bottom: 16px; }
.dash-grid > .form-card { margin: 0; min-width: 0; }
.dash-grid .wide { grid-column: 1 / -1; }
.globe-year { width: auto; min-height: 36px; font-weight: 700; }  /* 1.59.0: the board's year on the globe */
.globe-yoy ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 4px; }
.globe-yoy li { display: grid; grid-template-columns: 7.4em minmax(0, 1fr) 2.6em 5em; align-items: center; gap: 8px; font-size: .8rem; }
.globe-yoy li span { color: var(--muted); white-space: nowrap; }
.globe-yoy li i { display: block; height: 8px; border-radius: 4px; background: var(--viz-1); min-width: 2px; }
.globe-yoy li b { text-align: right; font-variant-numeric: tabular-nums; }
.globe-yoy li small { color: var(--muted); font-variant-numeric: tabular-nums; white-space: nowrap; }
.globe-yoy li.on span, .globe-yoy li.on b { color: var(--ink); font-weight: 800; }
.ch-heat .vh-cell { aspect-ratio: auto; height: 30px; }
.ch-heat-hours .viz-heat { gap: 2px; }
.ch-heat-hours .vh-cell { height: 22px; border-radius: 3px; }
.ch-heat-hours .vh-cell i { display: none; }
tr.ch-live td { background: color-mix(in srgb, var(--esn-cyan) 7%, transparent); }  /* 1.60.0: this year in the history tables */
.viz-pace .pace-line { fill: none; stroke-linecap: round; stroke-linejoin: round; }
.viz-pace .pace-line.past { stroke: var(--muted); stroke-width: 1.2; opacity: .45; }
.viz-pace .pace-line.last { stroke: var(--viz-2); stroke-width: 2; }
.viz-pace .pace-line.now { stroke: var(--viz-1); stroke-width: 3; }
.viz-pace .pace-end { stroke: var(--card); stroke-width: 2; }
.viz-pace .pace-end.last { fill: var(--viz-2); }
.viz-pace .pace-end.now { fill: var(--viz-1); }
.viz-pace .hit { fill: transparent; outline: none; }
.viz-pace .hit:hover, .viz-pace .hit:focus-visible { fill: var(--hover); opacity: .5; }
.pace-key { display: inline-block; width: 18px; height: 3px; border-radius: 2px; margin-right: 6px; vertical-align: middle; }
.pace-key.now { background: var(--viz-1); height: 4px; }
.pace-key.last { background: var(--viz-2); }
.pace-key.past { background: var(--muted); opacity: .5; }
.ch-heat .viz-heat { overflow-x: auto; }
.ch-moves { list-style: none; margin: 6px 0 0; padding: 0; }  /* 1.59.0: ESNcard history, biggest changes */
.ch-moves li { display: flex; align-items: center; gap: 10px; padding: 6px 0; border-top: 1px solid var(--border); font-size: .9rem; }
.ch-moves li:first-child { border-top: 0; }
.ch-moves li .flagged { flex: 1; min-width: 0; }
.ch-moves b { min-width: 3.4em; text-align: right; font-variant-numeric: tabular-nums; }
.ch-moves b.up { color: var(--green-text); }
.ch-moves b.down { color: var(--magenta-text); }
.dash-title { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; flex-wrap: wrap; margin-bottom: 2px; }
.dash-title strong { font-size: .95rem; }
.dash-title .form-hint { margin: 0; }
.dash-sub { font-size: .8rem; color: var(--muted); margin: 0 0 6px; }
.dash-note { display: flex; gap: 8px; align-items: flex-start; font-size: .8rem; color: var(--muted); margin: 8px 0 0; }
.dash-note .material-symbols-rounded { font-size: 16px; color: var(--esn-cyan); flex: none; }
.dash-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 4px; }
.dash-list li { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 4px 6px; border-radius: var(--r-sm); background: var(--surface2); font-size: .85rem; }
.dash-list li a { color: var(--ink); font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* patterns: what the numbers say, before anyone interprets them */
.patterns { list-style: none; margin: 8px 0 0; padding: 0; display: grid; gap: 8px; }
.patterns li { display: grid; grid-template-columns: 26px 1fr; gap: 8px; align-items: start; padding: 8px 10px; border-radius: 10px; background: var(--surface2); }
.patterns .material-symbols-rounded { font-size: 20px; color: var(--esn-cyan); }
.patterns li.warn .material-symbols-rounded { color: var(--viz-serious); }
.patterns li.good .material-symbols-rounded { color: var(--viz-good); }
.patterns b { display: block; font-size: .9rem; }
.patterns small { color: var(--muted); font-size: .75rem; }
/* Jacob */
.jacob-box { border: 1px solid var(--border); border-radius: var(--r-md); padding: 12px 14px; background: linear-gradient(135deg, rgba(122, 76, 219, .08), rgba(0, 174, 239, .06)); }
.jacob-box.off { background: var(--surface2); }
.jacob-box .jacob-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.jacob-box .jacob-head strong { flex: 1; }
.jacob-ask { display: flex; gap: 8px; margin-top: 8px; }
.jacob-ask input { flex: 1; min-width: 0; }
.jacob-facts { margin-top: 8px; }
.jacob-facts summary { cursor: pointer; }
.jacob-facts pre { font-size: .75rem; white-space: pre-wrap; background: var(--surface2); padding: 8px; border-radius: var(--r-sm); max-height: 240px; overflow: auto; }
.chart-axis { stroke: var(--border); stroke-width: 1; }  /* 1.12.0: The globe */
html[data-theme="dark"] .kpi-delta.bad { color: #ff8a8a; }  /* 1.29.4: one system */
.kpi-delta.good { color: #1f7f1f; }  /* 1.29.4: colour follow-ups */
html[data-theme="dark"] .kpi-delta.good { color: var(--viz-good); }
/* Rows with a label, a hint and a number: the hint wraps under the label,
   the number keeps its column. */
.dash-list li > span:first-child { flex: 1 1 auto; min-width: 0; }  /* 1.40.0: mobile polish from the September screenshots */
.dash-list li .vb-val { flex: 0 0 auto; max-width: 45%; }
@media (max-width: 640px) {
  .viz-cols text, .viz-line text, .viz-dots text { font-size: 19px; }  /* 1.14.1: one button */
  .viz-cols text.lbl, .viz-line text.lbl, .viz-dots text.lbl { font-size: 20px; }
}
@media (prefers-reduced-motion: no-preference) {
  .an-section.an-armed .vb-fill, .an-section.an-armed .vf-fill, .an-section.an-armed .vd-fill { transform: scaleX(0); transform-origin: left; transition: transform .8s cubic-bezier(.2, .8, .2, 1); transition-delay: calc(var(--i, 0) * 40ms + .1s); }
  .an-section.an-armed.in .vb-fill, .an-section.an-armed.in .vf-fill, .an-section.an-armed.in .vd-fill { transform: none; }
  .an-section.an-armed .vh-cell { opacity: 0; transition: opacity .4s ease; }
  .an-section.an-armed.in .vh-cell { opacity: 1; }
  .an-section.an-armed.still .vb-fill { transform: none; animation: none; transition: none; }
  .an-section.an-armed.still .vf-fill { transform: none; animation: none; transition: none; }
  .an-section.an-armed.still .vd-fill { transform: none; animation: none; transition: none; }
  .an-section.an-armed.still .vh-cell { opacity: 1; }
}

/* ---------- Tables ---------- */
.table-wrap {
  overflow-x: auto;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  margin-bottom: 30px;
}
table { width: 100%; border-collapse: collapse; font-size: .85rem; font-variant-numeric: tabular-nums; }
th { text-align: left; padding: 11px 16px; color: var(--muted); font-weight: 700; text-transform: uppercase; white-space: normal; background: transparent; border-bottom: 2px solid var(--border); font-size: .75rem; letter-spacing: .7px; padding-top: 10px; padding-bottom: 10px; }  /* 1.78.7: headers wrap when the table is tight, instead of pushing it sideways */
td { text-align: left; padding: 11px 16px; border-bottom: 1px solid var(--border); padding-top: 10px; padding-bottom: 10px; }
tr:last-child td { border-bottom: none; }
tr:hover td { background: var(--hover); }
tr.pay-check { background: var(--danger-soft); }  /* 1.1.21: Payments log */
tbody tr { transition: background .1s ease; }
.table-wrap thead th:first-child { border-top-left-radius: var(--radius); }  /* 1.27.0: one whole */
.table-wrap thead th:last-child { border-top-right-radius: var(--radius); }
td.card-actions { white-space: nowrap; }  /* 1.29.1: row actions and row icons in admin tables */
td.card-actions > * + * { margin-left: 4px; }
td.card-actions .more-menu > summary.btn-ico { list-style: none; }
.row-ic { display: inline-flex; align-items: center; justify-content: center; width: 26px; height: 26px; margin-right: 8px; border-radius: var(--r-sm); vertical-align: middle; color: var(--c, var(--esn-cyan)); background: color-mix(in srgb, var(--c, var(--esn-cyan)) 14%, transparent); flex: none; }
.row-ic .material-symbols-rounded { font-size: 16px; }
tr.row-dim td { opacity: .55; }
tr.row-dim td.card-actions { opacity: 1; }
td.card-actions > .btn:first-child:not(.btn-ico) { min-width: 128px; justify-content: center; }
/* 1.78.2: the admin events table fits a laptop screen on ONE line per row: a fixed column layout (the table can
   never grow wider than its box), the title truncates with an ellipsis (the full title is on hover), the status is a
   small badge and the team badge is its icon with the audience on hover, and on a narrow laptop the Edit and
   Registrations buttons are their icons. No horizontal scrolling down to 1024 px. */
#admin-events table { table-layout: fixed; }
#admin-events th:nth-child(2), #admin-events td:nth-child(2) { width: 150px; }
#admin-events th:nth-child(3), #admin-events td:nth-child(3) { width: 84px; }
#admin-events th:nth-child(4), #admin-events td:nth-child(4) { width: 150px; }
#admin-events th:nth-child(5), #admin-events td:nth-child(5) { width: 140px; }
#admin-events th:nth-child(6), #admin-events td:nth-child(6) { width: 150px; }
#admin-events th:nth-child(7), #admin-events td:nth-child(7) { width: 148px; }
#admin-events td { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
#admin-events td.card-actions { overflow: visible; }  /* 1.78.7: the row's More menu opens outside the cell */
#admin-events td.card-main a { display: inline; }
#admin-events td[data-l="Status"] .badge { font-size: .7rem; padding: 1px 7px; margin-right: 4px; vertical-align: middle; }
#admin-events td[data-l="Status"] .badge-ico { padding: 2px 5px; }
#admin-events td[data-l="Status"] .badge-ico .material-symbols-rounded { font-size: 15px; vertical-align: -3px; }
#admin-events .sold-bar { max-width: 110px; }
#admin-events td.card-actions > .btn:first-child:not(.btn-ico) { min-width: 0; }
@media (min-width: 821px) {
  #admin-events td.card-actions .ev-edit-label, #admin-events td.card-actions .ev-reg-label { display: none; }  /* 1.78.7: three icon buttons with tooltips; the text cut the last one off between 1180 and 1360 px */
}
@media (max-width: 1360px) and (min-width: 821px) {
  #admin-events th, #admin-events td { padding-left: 10px; padding-right: 10px; }
}
@media (max-width: 1180px) and (min-width: 821px) {
  #admin-events td:nth-child(2) small { display: none; }
  #admin-events th:nth-child(3), #admin-events td:nth-child(3) { width: 92px; }
  #admin-events th:nth-child(4), #admin-events td:nth-child(4) { width: 124px; }
  #admin-events .sold-bar { max-width: 84px; }
}
.data-table td { font-size: .8rem; vertical-align: top; }  /* 1.31.0: the Section card and the data-model fold on Settings */
.data-table td:first-child { white-space: nowrap; }
@media (min-width: 821px) {
  tbody tr:hover { background: var(--hover); }
}
@media (max-width: 820px) {
  th, td { padding: 10px; }  /* Responsive */
  td { font-size: .8rem; }
  /* Tables marked .cards become stacked cards on mobile — no sideways scrolling */
  .table-wrap.cards { background: none; border: none; box-shadow: none; overflow: visible; }
  .cards td.card-actions {
    justify-content: flex-start;
    flex-wrap: wrap;
    gap: 6px;
    padding-top: 6px;
    text-align: left;
    white-space: normal !important;
  }
  /* app-like: no visible scrollbars on scrollable strips */
  .table-wrap { scrollbar-width: none; }  /* v0.109.1: Design pass — playbook fundamentals */
  .table-wrap::-webkit-scrollbar { display: none; }
}
@media (max-width: 640px) {
  .cards td.card-actions > * + * { margin-left: 0; }  /* 1.14.1: one button */
  .cards td.card-actions { white-space: normal; }
  td.card-actions > * + * { margin-left: 0; }  /* 1.29.1: row actions and row icons in admin tables */
  td.card-actions > .btn:first-child:not(.btn-ico) { min-width: 0; }
}
@media (hover: hover) {
  .table-wrap tbody tr { transition: background var(--t-fast) ease; }
  .table-wrap tbody tr:hover { background: var(--hover); }
}

/* ---------- Forms ---------- */
/* Registration controls card on the admin event page (1.1.10). */
.regctl-head { display: flex; flex-wrap: wrap; gap: 8px 10px; align-items: center; }
.regctl-acts { display: flex; flex-wrap: wrap; gap: 6px; margin-left: auto; }  /* 1.66.0: the actions sit on the state line */
.regctl-row { margin: 10px 0 0; gap: 8px; }
.ev-toolbar { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin: 0 0 16px; }  /* 1.66.0: Scan, Export, Copy e-mails, Cancel */
.ev-toolbar .ev-toolbar-end { margin-left: auto; }
.regs-table th, .regs-table td { padding-left: 12px; padding-right: 12px; }  /* 1.66.0: the list fits a laptop without a sideways scroll */
.regs-table .td-email span { display: inline-block; max-width: 220px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; vertical-align: bottom; }
.sold-line { display: block; white-space: nowrap; }
.sold-bar { display: block; height: 5px; margin-top: 5px; border-radius: 3px; background: var(--surface2); overflow: hidden; max-width: 140px; }
.sold-bar i { display: block; height: 100%; background: var(--esn-cyan); border-radius: 3px; }
.sold-bar i.near { background: var(--esn-orange); }
.sold-bar i.full { background: var(--esn-green); }
/* Settings (1.1.15): unsaved marker per card/row + tab dot, venue placeholder, banner preview */
.form-card.dirty { box-shadow: inset 3px 0 0 var(--esn-orange); }  /* 1.1.15: Settings markers */
.form-card {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 22px;
  margin-bottom: 18px;
  min-width: 0;
}
.form-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 18px 20px; }  /* 1.66.0: minmax(0): an input never widens its column past the card */
.form-field { display: flex; flex-direction: column; gap: 6px; }
.form-field.full { grid-column: 1 / -1; }
.form-field label {
  font-weight: 700;
  font-size: .75rem;
  text-transform: uppercase;
  letter-spacing: .8px;
  color: var(--muted);
}
.form-field input, .form-field textarea, .form-field select,
.buy-box select {
  max-width: 100%; min-width: 0; box-sizing: border-box;  /* 1.66.0: never wider than the card */
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  font-family: inherit;
  font-size: .9rem;
  background: var(--card);
  color: var(--ink);
}
.form-field input:focus, .form-field textarea:focus, .form-field select:focus {
  outline: none;
  border-color: var(--accent-text);  /* 1.55.0: contrast */
  box-shadow: var(--ring-soft);
}
.form-field input:disabled { background: var(--bg); color: var(--muted); }
.form-actions { display: flex; gap: 10px; margin-top: 18px; flex-wrap: wrap; align-items: center; }
.inline-input.ho-doc { flex: 1 1 180px; min-width: 0; width: auto; }  /* 1.78.4: the handover document links shrink to the phone instead of running past it */
.form-hint { font-size: .8rem; color: var(--muted); }
.checkbox-row { display: flex; align-items: center; gap: 8px; }
.checkbox-row input { width: 17px; height: 17px; accent-color: var(--esn-dark); }
html[data-theme="dark"] .checkbox-row input { accent-color: var(--esn-cyan); }
.checkbox-row label { text-transform: none; letter-spacing: 0; font-size: .9rem; color: var(--ink); }
label.checkbox-row { text-transform: none; letter-spacing: 0; font-size: .9rem; color: var(--ink); flex-wrap: wrap; }  /* 1.78.4: a row that is itself the label reads like the other rows, not like a field label */
@media (max-width: 640px) { label.checkbox-row > small.form-hint { flex: 1 1 100%; margin-left: 25px; } }  /* 1.78.4: the option's note goes under it on a phone */
.inline-input {
  padding: 6px 10px;
  border: 1px solid var(--border);
  border-radius: 7px;
  font-family: inherit;
  font-size: .8rem;
  width: 150px;
  background: var(--card);
  color: var(--ink);
  transition: border-color var(--t-fast) ease, box-shadow var(--t-fast) ease;
}
/* Grid/flex children with inputs must be allowed to shrink —
   intrinsic input widths were forcing cards past the viewport. */
.form-grid, .form-grid .form-field { min-width: 0; }  /* v1.14: — mobile audit */
.form-field input, .form-field select, .form-field textarea { max-width: 100%; }
.form-field input {
  transition: border-color var(--t-fast) ease, box-shadow var(--t-fast) ease;
}  /* v0.109.1: Design pass — playbook fundamentals */
.form-field textarea {
  transition: border-color var(--t-fast) ease, box-shadow var(--t-fast) ease;
}
.form-field select {
  transition: border-color var(--t-fast) ease, box-shadow var(--t-fast) ease;
}
.checkbox-row span { font-size: .9rem; color: var(--ink); }  /* ESNcard form v1.2.0 */
.form-actions > .form-hint { margin-left: 2px; }  /* 1.14.1: one button */
.form-actions.toolbar { margin: 0 0 14px; align-items: center; }
.form-actions.toolbar > .spacer { flex: 1; }
/* Long help paragraphs read at a readable measure, not the full page width. */
#app > p.form-hint { max-width: 78ch; }
.form-card > p.form-hint:first-child { max-width: 78ch; }
.form-actions .fsel { margin: 0; }  /* 1.27.0: one whole */
/* Nudges (1.29.4): the one-time cards (first ticket, reminders) share one
   shape: a title line, one hint, buttons on the right. */
.form-card.nudge { margin: 0 0 14px; padding: 14px 16px; border-left: 4px solid var(--esn-cyan); }  /* 1.29.4: colour follow-ups */
.form-card.nudge > strong { display: flex; align-items: center; gap: 6px; font-size: .95rem; }
details.form-card > summary { list-style: none; }  /* 1.31.0: the Section card and the data-model fold on Settings */
details.form-card > summary::-webkit-details-marker { display: none; }
details.form-card > summary .form-hint { margin-left: 6px; }
details.form-card[open] > summary { margin-bottom: 4px; }
@media (max-width: 820px) {
  .form-grid { grid-template-columns: minmax(0, 1fr); }  /* Responsive */
  .form-card { padding: 16px; margin-bottom: 14px; }
  .form-actions .btn { flex: 1 1 calc(50% - 5px); white-space: nowrap; min-width: max-content; max-width: 100%; }
  .regctl-row .btn, .regctl-row .form-field { flex: 1 1 100%; }
  .regctl-acts { margin-left: 0; width: 100%; }
  .regctl-acts .btn { flex: 1 1 calc(50% - 6px); justify-content: center; }
  .ev-toolbar .btn { flex: 1 1 calc(50% - 8px); justify-content: center; }
  .ev-toolbar .ev-toolbar-end { margin-left: 0; }
  .ev-toolbar #btn-scan-here { flex: 1 1 auto; }  /* 1.78.7: one row: Scan, then icon buttons */
  .ev-toolbar #btn-csv, .ev-toolbar #btn-emails { flex: 0 0 auto; }
  .ev-toolbar .evt-lbl, .ev-head-actions .evh-lbl { display: none; }
  .ev-head { padding: 12px 14px 0; }
  .ev-head-title { flex: 1 1 0; }
  .ev-head-info { gap: 6px; margin: 10px 0 6px; }
  .kpi-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }  /* 1.78.7: number tiles half the height on a phone */
  .kpi { min-height: 0; padding: 10px 12px; }
  .kpi-n { font-size: 1.45rem; }
  .kpi-h { display: -webkit-box; -webkit-line-clamp: 1; -webkit-box-orient: vertical; overflow: hidden; }
  .regs-table .td-email span { max-width: 100%; }
  #btn-cancel-event { flex: 0 0 auto; min-width: 0; margin-left: auto; }
}
@media (max-width: 640px) {
  /* Action rows: a two-column grid, every button the same width, an odd
     last one across the row, labels wrap rather than spill. Hints, fields
     and selects take a row of their own. */
  .form-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; align-items: stretch; }  /* 1.14.1: one button */
  .form-actions > .btn, .form-actions > button, .form-actions > a, .form-actions > details { min-width: 0; white-space: normal; max-width: none; }
  .form-actions > .btn-block, .form-actions > .form-hint, .form-actions > .form-field, .form-actions > .seg, .form-actions > input, .form-actions > select, .form-actions > .inline-input, .form-actions > span, .form-actions > p { grid-column: 1 / -1; }
  .form-actions > .btn:last-child:nth-child(odd), .form-actions > button:last-child:nth-child(odd), .form-actions > a:last-child:nth-child(odd), .form-actions > details:last-child:nth-child(odd) { grid-column: 1 / -1; }
  .form-actions > details > summary { width: 100%; }
  .regctl-row .btn, .regctl-row .form-field { flex: none; }
  #btn-cancel-event { grid-column: 1 / -1; margin-left: 0; }
  /* a destructive or icon-only button never grows to fill the row */
  .form-actions > .btn-danger:last-child:nth-child(odd) { grid-column: auto; justify-self: start; }
  /* the tag rows under Settings: colour, icon and name on one line, then
     the two selects, then Save and delete */
  .form-actions.tag-row { grid-template-columns: 44px 44px 1fr 44px; }
  .form-actions.tag-row > .tag-color { grid-column: 1; }
  .form-actions.tag-row > .tag-icon { grid-column: 2; }
  .form-actions.tag-row > .tag-name { grid-column: 3 / -1; width: auto !important; }
  .form-actions.tag-row > .tag-esncause, .form-actions.tag-row > .tag-dsatype { grid-column: 1 / -1; width: auto !important; }
  .form-actions.tag-row > .badge { grid-column: 1 / -1; justify-self: start; }
  .form-actions.tag-row > .tag-save { grid-column: 1 / 4; }
  .form-actions.tag-row > .tag-del { grid-column: 4; }
  .form-actions > .btn { display: inline-flex; align-items: center; justify-content: center; }  /* 1.29.4: Headings */
}
@media (hover: hover) {
  .form-field input:hover:not(:focus), .form-field textarea:hover:not(:focus),
  .form-field select:hover:not(:focus) { border-color: #a9adc9; }  /* v0.109.1: Design pass — playbook fundamentals */
  html[data-theme="dark"] .form-field input:hover:not(:focus),
  html[data-theme="dark"] .form-field textarea:hover:not(:focus),
  html[data-theme="dark"] .form-field select:hover:not(:focus) { border-color: #4a4e78; }
}
@media (pointer: coarse) {
  .form-field input:not([type="checkbox"]):not([type="radio"]),
  .form-field select,
  .form-field textarea,
  .inline-input { min-height: 44px; }  /* 1.1.36: Form polish from the ticketing/ESNcard audit */
}

/* ---------- Guided form sections ---------- */
.form-section { border-top: 1px solid var(--border); padding-top: 22px; margin-top: 24px; }
/* Progressive event form (1.1.20): a locked section keeps its heading only */
.form-section.locked > :not(.form-section-head) { display: none; }
.form-section.locked .form-section-head { opacity: .6; margin-bottom: 0; }
.form-section.locked .form-section-head .form-hint:not(.lock-note) { display: none; }
.lock-note { display: none; margin: 2px 0 0; }
.locked .lock-note { display: block; }
.adv-panel.locked > summary .form-step { background: var(--muted) !important; }
.f-unfold { animation: f-unfold .25s ease-out; }
.tag-n { font-size: .7rem; font-weight: 800; padding: 1px 7px; border-radius: 10px; background: var(--esn-dark); color: #fff; letter-spacing: .02em; }
label.tag-main { border-color: var(--esn-dark) !important; box-shadow: 0 0 0 1px var(--esn-dark); }
.form-section.first { border-top: none; padding-top: 0; margin-top: 0; }
.form-section-head { display: flex; gap: 12px; align-items: flex-start; margin-bottom: 16px; }
.form-section-head strong { font-size: .95rem; }
.form-section-head .form-hint { margin-top: 1px; }
.form-step {
  flex: none;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  color: #fff;
  font-weight: 900;
  font-size: .8rem;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-top: 1px;
  background: var(--esn-dark);
}
.esn-subcard {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 16px 18px;
}
.field-error {
  border-color: var(--esn-magenta) !important;
  box-shadow: 0 0 0 3px rgba(236, 0, 140, .18) !important;
}
.field-error.shake { animation: fieldShake .28s linear; }  /* 1.78.16: a short no-shake when the field is wrong (off under reduced motion) */
.field-msg { margin: 6px 0 0; color: var(--magenta-text); font-size: .8rem; font-weight: 700; flex-basis: 100%; }  /* 1.55.0: the words next to a wrong field */
.field-msg .material-symbols-rounded { vertical-align: -3px; }
.option-head {
  display: grid;
  grid-template-columns: 1fr 90px 90px 70px 118px 40px;
  gap: 8px;
  font-size: .75rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .6px;
  color: var(--muted);
  padding: 0 2px;
  margin-bottom: 4px;
}
/* The numbered form sections were <strong>, so a screen reader saw one
   heading on the whole page and could not jump between them. */
.form-section-head h3 {
  margin: 0;
  font-size: 1rem;
  font-weight: 900;
  color: var(--ink);
  line-height: 1.3;
}  /* 1.1.36: Form polish from the ticketing/ESNcard audit */
.form-section.locked .form-step { background: var(--grey-fill); }  /* 1.29.4: one system */
@media (max-width: 820px) {
  /* ticket-type / variant rows: name on its own line, numbers below */
  .option-head { display: none; }  /* Responsive */
}

/* ---------- Back chip on detail banners ---------- */
.back-chip {
  display: inline-block;
  color: #c7cbf2;
  font-weight: 700;
  font-size: .8rem;
  margin-bottom: 10px;
}
.back-chip:hover { color: #fff; text-decoration: none; }
.back-chip.back-chip-plain { padding: 8px 12px 8px 8px; min-height: 34px; border-radius: 7px; background: var(--card); border: 1px solid var(--border); display: inline-flex; align-items: center; gap: 4px; margin: 0 0 12px; color: var(--accent-text); font-size: .9rem; font-weight: 700; text-decoration: none; }  /* 1.23.1: Crumb */
.back-chip.back-chip-plain:hover { background: var(--hover); color: var(--esn-cyan); }
html[data-theme="dark"] .back-chip.back-chip-plain { color: var(--esn-cyan); }  /* v0.137: Product page */

/* ---------- Misc ---------- */
.empty-state .big .material-symbols-rounded { font-size: 56px; color: var(--muted); }
.empty-state { text-align: center; padding: 60px 20px; color: var(--muted); }
.empty-state .big { font-size: 2.4rem; margin-bottom: 10px; }
.error-state .row-actions { display: flex; gap: 10px; justify-content: center; flex-wrap: wrap; margin-top: 14px; }
.error-state strong { color: var(--ink); font-size: 1.05rem; }
/* While the next page's data loads, keep the current content visible but
   dimmed — the spinner only appears if loading takes noticeably long. */
#app.is-loading { opacity: .45; pointer-events: none; transition: opacity .15s ease; }
#app.is-loading:has(> .loading) { opacity: 1; pointer-events: auto; }  /* 1.78.7: the dim is for the old page; the loading screen itself (and its Try again) is never dimmed or dead */

/* ---------- Crumb: the back link (1.23.1) ---------- */
/* 1.23.1: one look for every back link, the chip the product page already
   had: a rounded pill with room above it, the arrow muted, the label ink. */
/* The same vocabulary as .chip and .btn-ghost (7-8px radius, card surface,
   muted text, .8rem bold): a back link reads as one of the site's own
   controls, not a shape of its own. */
.crumb { margin: 10px 0 14px; font-size: .8rem; font-weight: 700; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.crumb a, p.crumb a:not(.btn), html[data-theme="dark"] .crumb a { display: inline-flex; align-items: center; gap: 4px; padding: 8px 12px 8px 8px; min-height: 34px; border-radius: 7px; background: var(--card); border: 1px solid var(--border); color: var(--muted); text-decoration: none; transition: background var(--t-fast) ease, color var(--t-fast) ease, border-color var(--t-fast) ease; }  /* 1.78.0: the selectors outrank the dark-theme link colour and the underline of links in a paragraph */
.crumb a .material-symbols-rounded { font-size: 16px; }
.crumb a:hover, html[data-theme="dark"] .crumb a:hover { background: var(--hover); color: var(--accent-text); text-decoration: none; }
.crumb .form-hint { font-weight: 500; }
.ev-note.mtg-ta { min-height: 2.6em; font-size: .85rem; padding: 8px 10px; }
.save-bar {
  position: sticky; bottom: 12px; z-index: 6; display: flex; align-items: center; justify-content: flex-end; gap: 12px;
  margin: 0 0 14px; padding: 8px 12px; background: var(--card); border: 1px solid var(--border); border-radius: var(--r-md); box-shadow: var(--shadow-lg);
}
.save-bar .form-hint.ok { color: var(--esn-green); }
.save-bar .form-hint.err, .save-bar .form-error { color: var(--danger); font-weight: 700; }
.danger-zone { border-left: 4px solid var(--danger); margin-top: 8px; }
/* With a crumb chip above it the event card sits closer to it */
.crumb + .event-detail { margin-top: 4px; }  /* 1.29.4: colour follow-ups */
@media (max-width: 820px) {
  /* The arrow in the bar replaces a crumb that is only a back link (1.1.43). */
  html.has-back .crumb-plain, html.has-back .back-chip-plain { display: none; }  /* Responsive */
  html.has-back .crumb { display: none; }  /* 1.78.7: the app bar's arrow is the way back; the page's heading says where you are */
  .dup-title:not(:has(.title-help)) { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; }  /* 1.78.7: the app bar already names the page */
  /* 1.78.7: the hidden title (or the hidden crumb) used to give the space under the app bar; whatever comes first now keeps it.
     1.78.9: through --under-bar also a first line with .pull-up or .m-0, whose !important margin used to win */
  #app > .dup-title:not(:has(.title-help)):first-child + *, html.has-back #app > .crumb:first-child + :not(.passport), html.has-back #app > .crumb:first-child + .dup-title:not(:has(.title-help)) + * { margin-top: 16px; --under-bar: 16px; }
}
@media (max-width: 640px) {
  .save-bar { bottom: calc(64px + env(safe-area-inset-bottom)); }
  /* above the bottom nav */
}

/* ---------- More menu (details popover) ---------- */
.more-menu { position: relative; display: inline-block; vertical-align: middle; }
.more-menu > summary { list-style: none; display: inline-flex; align-items: center; gap: 4px; }
.more-menu > summary::-webkit-details-marker { display: none; }
.more-menu-list {
  position: absolute; right: 0; top: calc(100% + 6px); z-index: 30; min-width: 240px; padding: 6px;
  display: flex; flex-direction: column; background: var(--card); border: 1px solid var(--border); border-radius: var(--r-md); box-shadow: var(--shadow-pop); max-width: min(320px, calc(100vw - 32px));
}
/* Menus: an item may wrap instead of being cut off */
.more-menu-list > * {
  display: flex; align-items: center; gap: 8px; text-align: left; padding: 9px 12px; border: 0; border-radius: var(--r-sm);
  background: none; font-family: inherit; font-size: .9rem; font-weight: 700; color: var(--ink); cursor: pointer; text-decoration: none; white-space: normal;
}
.more-menu-list > *:hover { background: var(--hover); text-decoration: none; }
.more-menu-list .material-symbols-rounded { color: var(--esn-cyan); }
.more-menu-list .menu-danger { color: var(--esn-magenta); }  /* 1.14.1: one button */
.more-menu-list .menu-danger .material-symbols-rounded { color: var(--esn-magenta); }
.more-menu-list > label { cursor: pointer; }
/* A More menu opens above whatever follows it: every direct child of #app is
   its own stacking context (the entrance animation leaves a transform on
   it), so the child that holds the open menu is lifted while it is open. */
#app > *:has(.more-menu[open]) { position: relative; z-index: 40; }  /* 1.15.0: colours per category */
/* 1.66.0: an open menu floats at the top of the page, out of any scrolling table or sticky bar (see floatMenu in app.js) */
.more-menu-list.menu-float { position: fixed; right: auto; bottom: auto; top: auto; height: auto; transform: none; z-index: 1200; max-width: calc(100vw - 16px); }
@media (max-width: 640px) {
  .more-menu-list { left: 0; right: auto; }
}

/* ---------- Loading, spinner, toast ---------- */
/* 1.1.16: undo toasts, preset chips in dialogs */
.toast .toast-x { margin-left: 6px; background: none; border: 0; color: inherit; opacity: .7; padding: 2px; line-height: 0; cursor: pointer; }  /* 1.1.15: Settings markers */
.toast .toast-x:hover { opacity: 1; }
.toast .toast-undo { margin-left: 10px; background: rgba(255,255,255,.18); border: 1px solid rgba(255,255,255,.5); color: inherit; border-radius: 999px; padding: 2px 10px; font: inherit; font-weight: 700; cursor: pointer; }
.loading { text-align: center; padding: 90px 0; color: var(--muted); }
/* 1.69.5: skeletons, the shape of the page that is coming. One light band
   sweeps across them (a transform on one layer, no repaint per frame). */
.loading.sk { position: relative; overflow: hidden; padding: 14px 0 24px; text-align: left; }
.loading.sk > p { text-align: center; }
.loading.sk .g-hero { margin-top: 0; }  /* 1.77.1: the hero sits where the page will put it, so the swap does not shift it */
.sk-line, .sk-img, .sk-hero, .sk-cal i { display: block; border-radius: 8px; background: color-mix(in srgb, var(--ink) 9%, var(--card)); }  /* a tone of the text colour: visible in both themes */
.sk-line { height: 12px; margin: 0 0 12px; }
.sk-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(260px, 100%), 1fr)); gap: 16px; margin-top: 18px; }
.sk-card { border: 1px solid var(--border); border-radius: var(--radius); background: var(--card); overflow: hidden; padding-bottom: 4px; }
.sk-card .sk-line { margin: 12px 14px 0; }
.sk-img { height: 150px; border-radius: 0; }
.sk-hero { height: 190px; border-radius: var(--radius); margin-bottom: 16px; }
.sk-btn > i { display: block; width: 190px; height: 44px; border-radius: var(--r-md); background: rgba(255, 255, 255, .25); }  /* 1.77.1: the sign-in button's place in the visitor's hero skeleton; 1.78.9: the row (app.js swaps it whole for the buttons), What's on beside it */
.sk-btn > i + i { width: 116px; background: rgba(255, 255, 255, .12); }
.sk-cal { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 6px; margin-top: 14px; }
.sk-cal i { aspect-ratio: 1; border-radius: 10px; }
@media (prefers-reduced-motion: no-preference) {
  .loading.sk::after { content: ""; position: absolute; inset: 0; pointer-events: none; background: linear-gradient(100deg, transparent 30%, rgba(255, 255, 255, .22) 50%, transparent 70%); transform: translateX(-100%); animation: sk-sweep 1.5s ease-in-out infinite; }
}
@keyframes sk-sweep { to { transform: translateX(100%); } }
html[data-theme="dark"] .loading.sk::after { opacity: .35; }  /* the same sweep, quieter on dark */
.spinner {
  width: 38px; height: 38px;
  margin: 0 auto 14px;
  border: 3px solid var(--border);
  border-radius: 50%;
  border-width: 3px;
  border-color: var(--border);
  border-top-color: var(--esn-cyan);
  border-right-color: var(--esn-magenta);
  animation: spin .7s cubic-bezier(.45, .2, .55, .8) infinite;
}
/* A toast never runs off the screen: it wraps, and a long link breaks */
/* The toast: fixed and centred, its available width was half the screen, so
   on a phone the text broke into single letters. Its own width now. */
.toast {
  position: fixed;
  bottom: 24px;
  left: 50%;
  transform: translateX(-50%);
  background: var(--esn-dark);
  color: #fff;
  padding: 12px 22px;
  font-weight: 700;
  font-size: .9rem;
  z-index: 100;
  box-shadow: var(--shadow-lg);
  border-radius: var(--r-md);
  display: flex;
  align-items: center;
  gap: 9px;
  animation: toastIn .32s cubic-bezier(.34, 1.45, .64, 1);
  max-width: calc(100vw - 32px);
  box-sizing: border-box;
  white-space: normal;
  overflow-wrap: anywhere;
  text-align: center;
  width: max-content;
}
.toast.error { background: var(--esn-magenta); }
.toast.warn { background: var(--esn-orange); }
/* guidance, not logged */
.toast.success { background: var(--esn-green); }
.success-panel {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 50px 30px;
  text-align: center;
  margin: 44px auto;
  max-width: 540px;
}
.success-panel .big { font-size: 2.8rem; }
/* 1.69.2: the tick draws itself: the ring first, then the stroke, with a small pop */
.success-mark { width: 76px; height: 76px; display: block; margin: 0 auto 8px; fill: none; stroke: var(--esn-green); stroke-width: 4; stroke-linecap: round; stroke-linejoin: round; animation: mark-pop .45s .55s cubic-bezier(.2, .7, .3, 1) both; }
.success-mark circle { stroke-dasharray: 176; stroke-dashoffset: 176; animation: mark-draw .55s cubic-bezier(.2, .7, .3, 1) forwards; }
.success-mark path { stroke-dasharray: 36; stroke-dashoffset: 36; animation: mark-draw .3s .45s cubic-bezier(.2, .7, .3, 1) forwards; }
@media (prefers-reduced-motion: reduce) {
  .success-mark circle, .success-mark path { stroke-dashoffset: 0; }
}
.success-panel h1 { margin: 10px 0; font-size: 1.45rem; }
html[data-theme="dark"] .toast { border: 1px solid rgba(255, 255, 255, .22); }
.toast.hidden { display: none; }
.toast.leaving { animation: toastOut .2s ease forwards; pointer-events: none; }  /* 1.55.0 */
.toast .material-symbols-rounded { flex: 0 0 auto; }
.toast > span { min-width: 0; }  /* 1.40.0: mobile polish from the September screenshots */
@media (max-width: 820px) {
  .success-panel { padding: 34px 20px; }  /* Responsive */
  .toast { bottom: calc(96px + env(safe-area-inset-bottom)); }
  /* above the tab bar */
}

/* ---------- Profile pictures (1.1.23) ---------- */
/* Profile pictures (1.1.23) */
.av { position: relative; width: 34px; height: 34px; border-radius: 50%; flex: none; display: inline-flex; align-items: center; justify-content: center; background: hsl(var(--h, 220) 45% var(--l, 40%)); color: #fff; font-weight: 900; font-size: .8rem; overflow: hidden; vertical-align: middle; }
.av img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.av i { font-style: normal; letter-spacing: .02em; }
/* 1.10.0: the initials sat underneath the photo and showed through it while
   it loaded, and for good whenever the image came back empty without firing
   an error. With a photo present they are hidden outright; the coloured disc
   is the loading state. A photo that fails removes itself (onerror), which
   makes the initials the first child again and brings them back. */
.av img + i { visibility: hidden; }
button .material-symbols-rounded, .btn .material-symbols-rounded { pointer-events: none; }  /* 1.78.4 (audit): a tap on the glyph is a tap on the button, so e.target is the button */
.av.av-sm { width: 30px; height: 30px; font-size: .7rem; }
.av.av-xs { width: 22px; height: 22px; font-size: .66rem; }
.av.av-xxs { width: 18px; height: 18px; font-size: .66rem; }
.av.av-lg { width: 44px; height: 44px; font-size: .95rem; }
.av.av-xl { width: 88px; height: 88px; font-size: 1.7rem; }

/* ---------- Stat cards ---------- */
/* The five pages that still use the older stat tiles wear the Insights look:
   same radius, padding and number size, the accent moved from a left bar
   to the soft glow. */
.stat-row {
  display: grid;
  gap: 10px;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  margin-bottom: 14px;
}
.stat-card {
  background: var(--card);
  border: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  justify-content: center;
  border-left: 1px solid var(--border);
  padding: 14px 14px 12px;
  box-shadow: none;
  position: relative;
  overflow: hidden;
  min-height: 96px;
  border-radius: var(--radius);
}
.stat-card .num { font-weight: 900; color: var(--ink); font-size: 1.7rem; letter-spacing: -.02em; line-height: 1.1; font-variant-numeric: tabular-nums; }
.stat-card .lbl {
  font-weight: 700;
  text-transform: none;
  letter-spacing: 0;
  font-size: .8rem;
  color: var(--ink);
  margin-top: 2px;
}
@media (max-width: 640px) {
  .stat-row { grid-template-columns: 1fr 1fr; gap: 8px; }
  .stat-card { min-height: 0; padding: 10px 12px; }  /* 1.78.7: four tiles no longer fill a phone's first screen */
  .stat-card .num { font-size: 1.45rem; }
  .stat-card .lbl { font-size: .75rem; }
}

/* ---------- Select filters, no-show warning (v0.91) ---------- */
/* Task timestamps, dropdown filters, no-show warning (v0.91) */
.todo-when { display: block; color: var(--muted); font-size: .75rem; font-weight: 400; margin-top: 1px; }
/* The filter box sits directly above its select, so it should be the same
   width - at 220px it truncated its own placeholder inside a form field. */
/* 1.78.1: the searchable combobox that replaced the filter-above-a-select (wireSelectFilter) */
.combo { position: relative; display: inline-block; max-width: 100%; min-width: 220px; vertical-align: middle; }
.combo .combo-in { width: 100%; }
.combo .combo-native { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; left: 0; bottom: 0; }
.combo-list { position: absolute; z-index: 30; left: 0; right: 0; top: calc(100% + 4px); max-height: 260px; overflow-y: auto; margin: 0; padding: 4px; list-style: none; background: var(--card); border: 1px solid var(--border); border-radius: var(--r-md); box-shadow: var(--shadow-lg); }
.combo-list li { padding: 8px 10px; border-radius: 7px; font-size: .9rem; cursor: pointer; }
.combo-list li.is-hi, .combo-list li:hover { background: var(--hover); }
.combo-list li.is-sel { font-weight: 700; color: var(--accent-text); }
.combo-list .combo-none { color: var(--muted); cursor: default; }
.combo.combo-text { display: block; width: 100%; min-width: 0; }  /* 1.78.13: a text field with suggestions (suggest.js) takes the field's whole width */
.combo.combo-text > input { width: 100%; }
.combo.combo-text > .combo-list { min-width: 200px; }  /* a narrow field (a shift row's task on a phone) still gets a readable list */
.combo-list .combo-note { display: block; color: var(--muted); font-size: .8rem; font-weight: 400; }
.auto-filled { animation: auto-fill-glow 1.8s ease-out; }
.noshow-warn {
  background: rgba(244, 123, 32, .12);
  border: 1px solid rgba(244, 123, 32, .45);
  color: var(--ink);
  border-radius: 10px;
  padding: 10px 12px;
  font-size: .85rem;
  margin: 10px 0;
}
.noshow-warn .material-symbols-rounded { color: var(--esn-orange); }
.todo-when .material-symbols-rounded { font-size: 14px; }  /* 1.1.13: Election ballot */
@media (prefers-reduced-motion: reduce) {
  .auto-filled { animation: none; }
}

/* ---------- Image upload ---------- */
.img-preview {
  max-width: 260px;
  max-height: 160px;
  border-radius: var(--r-sm);
  border: 1px solid var(--border);
  object-fit: cover;
  display: block;
}
.img-upload-row { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }

/* ---------- Responsive: app-style mobile ---------- */
.cards tr.attn-soon { border-left: 3px solid var(--esn-orange); }  /* 1.1.15: Admin event header */
@media (max-width: 820px) {
  .d-only { display: none !important; }
  #btn-signout { display: none; }
  #user-name { display: none; }
  /* Screen transitions between tabs */
  #app.page-anim { animation: page-in .18s ease-out; }
  .cards table, .cards tbody { display: block; width: 100%; }
  .cards thead { display: none; }
  .cards tr {
    background: var(--card);
    border: 1px solid var(--border);
    border-radius: var(--r-md);
    box-shadow: var(--shadow);
    margin-bottom: 8px;
    padding: 10px 12px;
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    column-gap: 14px;
  }
  .cards td {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 12px;
    border: none;
    padding: 3px 0;
    font-size: .85rem;
    text-align: right;
  }
  .cards tr:has(+ .ev-note-row) { border-bottom-left-radius: 0; border-bottom-right-radius: 0; border-bottom: 0; margin-bottom: 0; }
  .cards tr.ev-note-row { border-top-left-radius: 0; border-top-right-radius: 0; border-top: 0; padding-top: 0; }
  .cards td[data-l]::before {
    content: attr(data-l);
    font-weight: 700;
    letter-spacing: .3px;
    color: var(--muted);
    text-align: left;
    flex: none;
    font-size: .75rem;
  }
  .cards td.card-main {
    display: block;
    text-align: left;
    font-size: .95rem;
    padding-bottom: 4px;
    margin-bottom: 2px;
  }
  .cards th[scope="row"] {
    display: block; width: auto; background: none; text-transform: none; letter-spacing: 0;
    font-size: .9rem; color: var(--ink); padding: 0 0 6px; border: none;
    margin-bottom: 6px; border-bottom: 1px solid var(--border);
  }
  .cards th[scope="row"] small { color: var(--muted); font-weight: 500; }
  .cards tr.ev-grp { background: none; border: 0; box-shadow: none; padding: 10px 2px 2px; margin: 4px 0 2px; }  /* 1.78.17: a group's heading, not a card */
  .cards tr.ev-grp th { display: block; background: none; padding: 0; border: 0; font-size: .9rem; }
  .cards tr:hover td { background: none; }
  .cards td:empty { display: none; }
  /* A cell holding only a proportional bar: full width, no label (1.1.46) */
  .cards td.bar-cell { display: block; padding: 6px 0 0; }
  .cards td[data-l] { flex: 0 1 auto; max-width: 100%; min-width: 0; flex-direction: row; align-items: baseline; justify-content: flex-start; text-align: left; gap: 5px; padding: 2px 0; overflow-wrap: anywhere; }  /* 1.78.7: label and value on one line, several per line (cards were a block per field) */
  .cards td[data-l]:has(input, select, textarea, .bar, .sold-bar) { flex-basis: 100%; }
  .cards td.card-main, .cards td.card-actions, .cards td:not([data-l]) { flex: 1 1 100%; }
  .cards td.tar { text-align: left; }
}
@media (max-width: 640px) {
  /* The full-submission row docks under its applicant card */
  .cards tr.app-detail-row { margin-top: -6px; border-top-left-radius: 0; border-top-right-radius: 0; padding-top: 8px; }  /* v1.1.0: Admin */
  .cards tr.app-detail-row td { display: block; text-align: left; padding: 0; }
  .cards tr:has(+ .app-detail-row) { margin-bottom: 0; border-bottom-left-radius: 0; border-bottom-right-radius: 0; }
  .cards tr.row-team { border-left: 3px solid var(--esn-dark); }  /* v1.3.0: Users tab */
  .cards tr.row-team > td:first-child { box-shadow: none; }
  .cards td[data-l="Applied"] { white-space: normal !important; }  /* v1.4.0: ESNcard work queue */
}

/* ---------- Sub-navigation chips ---------- */
.subnav-chips { margin: -10px 0 18px; display: inline-flex; gap: 2px; padding: 3px; background: var(--surface2); border: 1px solid var(--border); border-radius: 10px; }
.settings-tabs.subnav-chips { margin: 0 0 16px; }
.subnav-chips .chip { border: 0; background: transparent; border-radius: var(--r-sm); padding: 7px 12px; box-shadow: none; }  /* 1.27.1: filters behind one button */
.subnav-chips .chip:hover { background: var(--hover); color: var(--ink); }
.subnav-chips .chip.active { background: var(--card); box-shadow: var(--shadow); color: var(--esn-dark); }
html[data-theme="dark"] .subnav-chips .chip.active { background: #2f3266; color: #fff; box-shadow: none; }  /* 1.28.0: the toolbar */
html[data-theme="dark"] .subnav-chips .chip:hover { background: #2a2d5a; color: #fff; }
@media (max-width: 820px) {
  .settings-tabs.subnav-chips { margin: 0 -24px 16px; }
  .subnav-chips { display: flex; overflow-x: auto; margin: 0; padding-left: 3px; padding-right: 3px; }  /* 1.27.1: filters behind one button */
}
@media (max-width: 520px) {
  .settings-tabs.subnav-chips { margin: 0 -16px 16px; }
}

/* ---- In-app dialogs (confirm/prompt replacement) ---- */
.dlg-presets .chip { font-size: .8rem; }  /* 1.1.15: Settings markers */
body.dialog-open { overflow: hidden; }
.dialog-overlay {
  position: fixed;
  inset: 0;
  z-index: 220;
  background: rgba(15, 16, 40, .64); /* 1.69.5: a solid dim, no backdrop blur (it re-rendered the page under it every frame on weak phones) */
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  animation: dlgFade .18s ease-out;
}
.dialog-card {
  background: var(--card);
  color: var(--ink);
  border: 1px solid var(--border);
  border-radius: 18px;
  box-shadow: 0 24px 60px rgba(8, 9, 30, .38);
  padding: 22px;
  width: min(420px, 100%);
  animation: dlgPop var(--dur-fast) var(--ease-settle);  /* 1.78.16: settles in instead of bouncing */
}
.dialog-msg { font-size: .95rem; line-height: 1.6; }
.dialog-msg br + br { display: block; content: ""; margin-top: 6px; }
.dialog-actions {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  margin-top: 18px;
  flex-wrap: wrap;
}
.dialog-overlay.closing { animation: dlgFadeOut .16s ease-in forwards; }
/* 1.48.0: the update wall sits above everything and cannot be dismissed. */
.dialog-overlay.update-wall { z-index: 260; background: rgba(15, 16, 40, .82); }
/* 1.49.0: the passport share studio. A wider card; the preview sits on a
   checkerboard when the image is transparent, dark under white ink.
   1.78.16: the pictures as real tabs in a grid (no row to scroll sideways),
   what the picture is for above it, the buttons kept in reach at the bottom. */
.share-studio .dialog-card { width: min(560px, 100%); max-height: calc(100dvh - 32px); overflow-y: auto; padding: 18px; }
.share-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; margin-bottom: 12px; }
.share-title { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.share-h { margin: 0; font-size: 1.05rem; display: inline-flex; align-items: center; gap: 8px; }
.share-event { display: inline-flex; align-items: center; gap: 4px; margin-top: 4px; font-size: .9rem; font-weight: 700; }
.share-tabs { display: grid; grid-template-columns: repeat(auto-fit, minmax(118px, 1fr)); gap: 8px; margin-bottom: 12px; }
.share-tab { display: flex; align-items: center; justify-content: center; gap: 6px; min-height: 44px; padding: 8px 10px; border: 1.5px solid var(--border); border-radius: 12px; background: var(--card); color: var(--ink); font: inherit; font-size: .9rem; font-weight: 700; cursor: pointer; }
.share-tab:hover { background: var(--hover); }
.share-tab.active { background: var(--esn-dark); border-color: var(--esn-dark); color: #fff; box-shadow: inset 0 -4px 0 var(--esn-cyan); }
.share-hint { margin: 0 0 10px; font-size: .9rem; color: var(--muted); }
.share-opts { display: flex; flex-wrap: wrap; gap: 8px 16px; margin: 0 0 10px; }
.share-opt { display: inline-flex; align-items: center; gap: 8px; }
.share-opt-l { font-size: .8rem; font-weight: 700; color: var(--muted); }
.share-preview { display: flex; justify-content: center; padding: 12px; border-radius: var(--r-md); background: var(--surface2); }
.share-preview canvas { display: block; max-width: 100%; max-height: min(52dvh, 520px); width: auto; height: auto; border-radius: 8px; box-shadow: 0 8px 24px rgba(8, 9, 30, .22); }
.share-preview.clear { background: repeating-conic-gradient(#3a3d63 0% 25%, #2b2e52 0% 50%) 50% / 22px 22px; }
.share-preview.clear.dark-ink { background: repeating-conic-gradient(#f1f2f7 0% 25%, #dfe1ec 0% 50%) 50% / 22px 22px; }
.share-preview.clear canvas { box-shadow: none; }
.share-steps { margin: 10px 0 0; padding-left: 20px; font-size: .85rem; color: var(--muted); }
.share-steps li { margin: 2px 0; }
.share-steps strong { color: var(--ink); }
.share-actions { position: sticky; bottom: 0; z-index: 1; display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 8px; margin: 12px -18px -18px; padding: 12px 18px 18px; background: var(--card); border-top: 1px solid var(--border); }
@media (max-width: 820px) {
  .share-studio .dialog-card { max-height: 94dvh; border-radius: 18px 18px 0 0; }
  .share-actions .btn { flex: 1 1 0; justify-content: center; }
}
.dialog-overlay.closing .dialog-card { animation: dlgDrop var(--dur-quick) var(--ease-settle) forwards; }
@media (max-width: 820px) {
  .dialog-overlay { align-items: flex-end; padding: 0; }
  .dialog-card {
    width: 100%;
    border-radius: 22px 22px 0 0;
    border-bottom: none;
    padding: 24px 20px calc(24px + env(safe-area-inset-bottom));
    animation: dlgSheet .28s cubic-bezier(.32, .72, .33, 1);
  }
  .dialog-card::before {
    content: "";
    display: block;
    width: 42px; height: 4px;
    border-radius: 2px;
    background: var(--border);
    margin: -8px auto 14px;
  }
  .dialog-actions { flex-direction: column-reverse; }
  .dialog-actions .btn { width: 100%; padding: 12px; }
  .dialog-overlay.closing .dialog-card { animation: dlgSheetOut .18s ease-in forwards; }
}

/* ---- (i) hint popover — anchored bubble instead of a toast ---- */
.hint-pop {
  position: fixed;
  z-index: 210;
  background: var(--esn-dark);
  color: #fff;
  font-size: .8rem;
  line-height: 1.5;
  font-weight: 500;
  padding: 10px 13px;
  border-radius: 10px;
  box-shadow: 0 10px 30px rgba(8, 9, 30, .35);
  animation: dlgPop .18s ease-out;
}
html[data-theme="dark"] .hint-pop { background: #34366b; }
.tip-pop { width: auto; max-width: 260px; padding: 6px 10px; font-size: .8rem; line-height: 1.35; text-align: center; }  /* 1.27.0: one whole */

/* ---- Event/shop cards: lift + gentle photo zoom on hover ---- */

/* ---- Jacob, the AI mascot (v0.99.2) ---- */
.jacob-sm {
  width: 19px;
  height: 19px;
  vertical-align: -5px;
  margin-right: 2px;
}
.jacob-lg {
  width: 36px;
  height: 36px;
  flex: 0 0 36px;
}
/* 1.78.7: Jacob at work (ai-motion.js): a sparkle in a turning ring of the ESN colours, faint lines being written, the steps he goes through; then the answer word by word */
.ai-think { display: flex; align-items: center; gap: 14px; margin: 10px 0 0; padding: 14px 16px; border: 1px solid var(--border); border-radius: var(--r-md); background: var(--card); }
.ai-orb { position: relative; isolation: isolate; flex: none; display: grid; place-items: center; width: 40px; height: 40px; border-radius: 50%; background: var(--esn-dark); color: #fff; }
.ai-orb::before { content: ""; position: absolute; inset: -3px; z-index: -1; border-radius: 50%; background: conic-gradient(var(--esn-cyan), var(--esn-magenta), var(--esn-orange), var(--esn-green), var(--esn-cyan)); }
.ai-orb .material-symbols-rounded { font-size: 22px; }
.ai-think-main { flex: 1; min-width: 0; }
.ai-steps { position: relative; display: block; height: 1.4em; font-size: .9rem; font-weight: 700; color: var(--ink); }
.ai-steps span { position: absolute; inset: 0 auto auto 0; white-space: nowrap; }
.ai-steps span + span { opacity: 0; }
.ai-lines { display: block; }
.ai-lines i { display: block; height: 8px; margin-top: 7px; border-radius: 4px; background: linear-gradient(90deg, var(--surface2) 0%, color-mix(in srgb, var(--esn-cyan) 40%, var(--surface2)) 50%, var(--surface2) 100%); background-size: 200% 100%; }
.ai-lines i:nth-child(1) { width: 92%; }
.ai-lines i:nth-child(2) { width: 76%; }
.ai-lines i:nth-child(3) { width: 54%; }
.ai-busy { background-image: linear-gradient(90deg, transparent 0%, color-mix(in srgb, var(--esn-cyan) 14%, transparent) 50%, transparent 100%); background-size: 200% 100%; }
@keyframes ai-step { 0% { opacity: 0; transform: translateY(6px); } 6%, 30% { opacity: 1; transform: none; } 36%, 100% { opacity: 0; transform: translateY(-6px); } }
@keyframes ai-scan { from { background-position: 100% 0; } to { background-position: -100% 0; } }
@keyframes ai-pulse { 0%, 100% { transform: scale(.88); } 50% { transform: scale(1.08); } }
@keyframes ai-word { from { opacity: 0; filter: blur(4px); transform: translateY(2px); } }
@media (prefers-reduced-motion: no-preference) {
  .ai-orb::before { animation: spin 2.4s linear infinite; }
  .ai-orb .material-symbols-rounded { animation: ai-pulse 1.6s ease-in-out infinite; }
  .ai-steps span { opacity: 0; animation: ai-step 4.8s ease-in-out infinite; animation-delay: calc(var(--i, 0) * 1.6s); }
  .ai-lines i, .ai-busy { animation: ai-scan 1.4s ease-in-out infinite; }
  .ai-lines i:nth-child(2) { animation-delay: .15s; }
  .ai-lines i:nth-child(3) { animation-delay: .3s; }
  .ai-w { display: inline-block; animation: ai-word .4s ease both; }
  .ai-typing { caret-color: var(--esn-cyan); }
}
.jacob-card {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  background: var(--hover);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  padding: 12px 14px;
  margin-top: 10px;
  font-size: .9rem;
  animation: viewIn 0.3s ease;
}

/* ---------- Form statics, PDF tile, unread dot ---------- */
/* Static read-only field on forms */
.form-label-static { display: block; font-size: .75rem; font-weight: 800; text-transform: uppercase; letter-spacing: .6px; color: var(--muted); margin-bottom: 4px; }
.form-static { margin: 0 0 4px; font-weight: 700; }
.iban-saved { display: flex; align-items: center; gap: 10px; margin-bottom: 6px; }
.iban-saved .mono { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-weight: 700; letter-spacing: .5px; }
.pdf-tile { display: inline-flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px; width: 110px; height: 90px; background: var(--surface2); border: 1px solid var(--border); border-radius: 10px; font-size: .75rem; color: var(--muted); text-align: center; padding: 6px; }
.pdf-tile .material-symbols-rounded { font-size: 28px; color: var(--danger); }
/* Menu unread dot (What's new) */
.unread-dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; background: var(--esn-magenta); margin-left: 6px; vertical-align: middle; }
.plain-link { color: inherit; }
.faq-link { margin: 8px 0 0; font-size: .8rem; }
.todo-overdue-count { color: var(--danger); }

/* ---- Colour language (v1.4.0): green = yes, red = no / destructive ---- */
/* Text-like buttons still get a 30px hit area */
.btn-link { background: none; border: 0; padding: 2px 0; margin-top: 4px; font: inherit; font-size: .8rem; color: var(--accent-text); cursor: pointer; gap: 2px; min-height: 30px; display: inline-flex; align-items: center; }
.btn-link:hover { text-decoration: underline; }
html[data-theme="dark"] .btn-link { color: var(--esn-cyan); }

/* ---------- Medals ---------- */
.medal .material-symbols-rounded { font-size: 16px; vertical-align: -4px; }
.medal-1 { color: #D4A017; }
.medal-2 { color: #9AA3AD; }
.medal-3 { color: #B87333; }
.legend .badge { margin: 0 2px; }
@media (max-width: 1100px) {
  .col-wide { display: none !important; }
}

/* ---- Section jump bar (1.1.32) --------------------------------------
   Long admin pages (Finance) get a sticky row of links so refunds,
   reimbursements and the cash registers are one tap apart on a phone
   instead of a long scroll. */
.jump-bar {
  position: sticky;
  top: 0;
  z-index: 5;
  display: flex;
  gap: 6px;
  overflow-x: auto;
  scrollbar-width: none;
  padding: 8px 0 10px;
  margin: 0 0 6px;
  background: var(--bg);
}
.jump-bar::-webkit-scrollbar { display: none; }
.jump-bar > a,
.jump-bar > button {
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  border: 1px solid var(--border);
  background: var(--card);
  color: var(--ink);
  border-radius: 20px;
  padding: 6px 12px;
  font: inherit;
  font-size: .85rem;
  font-weight: 700;
  cursor: pointer;
  white-space: nowrap;
}
.jump-bar > a:hover,
.jump-bar > button:hover { border-color: var(--esn-cyan); text-decoration: none; }
.jump-bar b {
  background: var(--esn-orange);
  color: var(--on-bright);  /* 1.55.0: contrast */
  border-radius: 10px;
  padding: 0 6px;
  font-size: .75rem;
}

/* ---- Event icons, used properly (1.1.33) -----------------------------
   Every event already carries a material icon (from its tag, or set in the
   form). It only appeared on passport stamps; now it marks the event on the
   card, the event page and in compact lists. */
.ev-title-ico {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  flex: none;
  border-radius: 11px;
  background: rgba(255, 255, 255, .18);
  border: 1px solid rgba(255, 255, 255, .3);
}
.ev-title-ico .material-symbols-rounded { font-size: 20px; }

/* ---------- Calm everywhere else ----------
   One tactile press on every button in the app. Somebody checking people in
   at a door at midnight does not want theatre, but they do want to feel that
   the tap registered. */
/* The door. Checking in is the single most-seen moment in the app: every
   student, every event, usually while somebody else waits behind them. */
.checkin-win { animation: pp-checkin-win .75s cubic-bezier(.34, 1.56, .64, 1) both; }
.checkin-win .material-symbols-rounded { display: inline-block; animation: pp-tick 1.6s .3s ease-in-out; }
/* Colophon at the foot of What's new (1.8.2). Deliberately quiet: findable
   if you look, invisible if you are not looking for it. */
.about-line {
  display: flex; align-items: center; justify-content: center; gap: 10px;
  margin: 28px auto 6px; max-width: 560px;
  font-size: .8rem; line-height: 1.5; color: var(--muted); text-align: left;
}
.about-line img { flex: none; width: 26px; height: auto; opacity: .75; }

/* ---- 1.14.1: one button, one gap, everywhere ----
   Every .btn is a flex box of the same height whether it holds an icon or
   not (an icon used to add up to four pixels), icon and label sit 6px apart
   instead of "whatever the whitespace gave", and the things that used to
   stack or touch (a menu under a button in a table cell, row actions with
   only a space between them, 25px icon buttons) get the same 6 to 10px
   rhythm as a .form-actions row. */
.btn-count::before { content: "("; }
.btn-count::after { content: ")"; }
@media (max-width: 640px) {
  .form-actions > .btn-icon { grid-column: auto; justify-self: start; min-width: 44px; }
}

/* ---- 1.27.1: filters behind one button, numbers right, segmented sub-tabs ---- */
html[data-theme="dark"] .filter-pop.is-set > summary { color: var(--esn-cyan); }

/* ---- 1.28.0: the toolbar, designed ---- */
.tb-count { margin: -4px 0 10px; font-size: .8rem; }
.bulk-bar { margin: 0 0 10px; padding: 8px 10px; border-radius: 10px; background: color-mix(in srgb, var(--esn-green) 12%, var(--card)); border: 1px solid color-mix(in srgb, var(--esn-green) 45%, var(--border)); }

/* ---------- 1.29.4 colour follow-ups ---------- */
/* A level colour used as text: darkened on light surfaces, as is in the dark theme */
.lc-text { color: color-mix(in srgb, var(--lc) 72%, #000); font-weight: 800; }
html[data-theme="dark"] .lc-text { color: var(--lc); }
.nudge-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 10px; flex-wrap: wrap; }

/* ============================================================
   PAGES AND FEATURES
   ============================================================ */

/* ---------- Hero ---------- */
.hero {
  margin: 28px 0 8px;
  border-radius: var(--radius);
  padding: 40px 40px 36px;
  color: #fff;
  background: var(--esn-dark);
  border-bottom: 4px solid var(--esn-cyan);
  box-shadow: var(--shadow);
}
.hero h1 { font-size: 1.7rem; font-weight: 900; margin-bottom: 8px; max-width: 640px; }
.hero p { max-width: 560px; color: #d9dbf2; margin-bottom: 20px; font-size: .95rem; }

/* ---- Event form v0.83: advanced panel, publish bar, geo results ---- */
.adv-panel {
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background: var(--bg);
  margin: 6px 0 18px;
}
.adv-panel > summary {
  display: flex;
  gap: 12px;
  align-items: center;
  padding: 14px 16px;
  cursor: pointer;
  list-style: none;
}
.adv-panel > summary::-webkit-details-marker { display: none; }
.adv-panel > summary::after {
  content: "expand_more";
  font-family: "Material Symbols Rounded";
  margin-left: auto;
  color: var(--muted);
  transition: transform .15s;
}
.adv-panel[open] > summary::after { transform: rotate(180deg); }
.adv-body { padding: 2px 16px 16px; display: flex; flex-direction: column; }
.adv-heading {
  font-weight: 800;
  font-size: .85rem;
  margin: 18px 0 10px;
  padding-top: 14px;
  border-top: 1px dashed var(--border);
}
.adv-body .adv-heading:first-child { border-top: none; padding-top: 0; margin-top: 4px; }
.publish-bar {
  position: sticky; bottom: 0; z-index: 6;
  background: var(--card); border-top: 1px solid var(--border); box-shadow: 0 -6px 18px rgba(25, 26, 46, .08);
  padding: 12px 22px; margin: 8px -22px -22px; border-radius: 0 0 var(--radius) var(--radius);
  display: flex;
  flex-direction: column;
  gap: 12px;
  border-top: 1px solid var(--border);
  padding-top: 16px;
}
.geo-results {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-top: 8px;
}
.geo-hit {
  display: flex;
  gap: 8px;
  align-items: flex-start;
  text-align: left;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--card);
  padding: 8px 12px;
  cursor: pointer;
  font-family: inherit;
  font-size: .85rem;
  color: var(--ink);
}
.geo-hit:hover { border-color: var(--esn-cyan); background: var(--hover); }
.geo-hit small { color: var(--muted); }
/* Home-city autocomplete: suggestions float over the form, not inside it */
.city-suggest { position: relative; z-index: 6; }
.city-suggest .geo-results {
  position: absolute;
  top: 4px; left: 0; right: 0;
  margin-top: 0;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 10px;
  box-shadow: var(--shadow-pop);
  padding: 6px;
  max-height: 240px;
  overflow-y: auto;
}
/* Ticket policy box in the buy box */
.policy-box {
  margin: 10px 0 4px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--bg);
  font-size: .85rem;
}
.policy-box summary {
  padding: 9px 12px;
  cursor: pointer;
  font-weight: 700;
  list-style-position: inside;
}
.policy-box ul { margin: 0; padding: 0 14px 10px 26px; }
.policy-box li { margin-bottom: 6px; }
.policy-agree-row { margin: 8px 0 10px; font-size: .9rem; }
.adv-panel.locked > summary { pointer-events: none; opacity: .6; }
.adv-panel.locked > summary::after { content: "lock"; }
.adv-panel.locked > summary .form-hint:not(.lock-note) { display: none; }
/* 1.52.0: the event form on a phone. The parts of the form as a sticky row
   of steps (done ones green, locked ones faded), and a publish bar of one
   row: save, publish, and the rest behind one button. What is still missing
   is one line that jumps to it; "Students see" stays for wider screens. */
.ef-steps { position: sticky; top: var(--hdr, 0px); z-index: 7; display: flex; gap: 6px; overflow-x: auto; scrollbar-width: none; margin: -22px -22px 18px; padding: 10px 22px; background: var(--card); border-bottom: 1px solid var(--border); border-radius: var(--radius) var(--radius) 0 0; }
.ef-steps a { flex: none; display: inline-flex; align-items: center; gap: 6px; padding: 5px 12px 5px 5px; border-radius: 999px; border: 1px solid var(--border); color: var(--ink); font-size: .8rem; font-weight: 700; text-decoration: none; white-space: nowrap; background: var(--card); }
.ef-steps a[aria-current] { border-color: var(--accent-text); box-shadow: 0 0 0 1px var(--accent-text) inset; }
.ef-steps .ef-n { width: 22px; height: 22px; border-radius: 50%; display: inline-grid; place-items: center; font-size: .75rem; background: var(--surface2); color: var(--ink); }
.ef-steps .ef-n .material-symbols-rounded { font-size: 15px; }
.ef-steps a.done .ef-n { background: var(--esn-green); color: var(--on-bright); }  /* 1.55.0: contrast */
.ef-steps a.locked { color: var(--muted); border-style: dashed; }  /* 1.78.4: was opacity .5 */
#event-form .form-section, #event-form .adv-panel { scroll-margin-top: calc(var(--hdr, 0px) + 64px); }
.pb-actions { margin: 0; align-items: flex-end; }
.pb-more { display: none; }
.pb-menu { top: auto; bottom: calc(100% + 6px); }
#f-required { cursor: pointer; }
#f-required:not([hidden]) { color: var(--accent-text); font-weight: 700; }
@media (max-width: 640px) {
  .publish-bar { position: fixed; left: 0; right: 0; margin: 0; padding: 8px 12px; gap: 6px; bottom: calc(60px + env(safe-area-inset-bottom)); border-radius: 0; z-index: 9; }  /* 1.66.0: a fixed bar above the tab bar instead of a sticky one that floated over the fields */
  #event-form { padding-bottom: 84px; }
  .ef-steps a { padding: 5px 10px 5px 5px; font-size: .75rem; }
  .ef-steps { margin: -16px -16px 14px; padding: 8px 12px; }
  .publish-bar .pb-actions { display: flex; flex-wrap: nowrap; align-items: center; gap: 8px; }
  .publish-bar .pb-actions > .btn .material-symbols-rounded { margin-right: 2px; }
  .publish-bar .pb-actions > .btn { flex: 1 1 0; min-width: 0; min-height: 44px; white-space: nowrap; }
  .publish-bar .pb-actions > .pb-sec { display: none; }
  .publish-bar .pb-more { display: inline-block; flex: none; }
  .publish-bar .pb-more > summary { min-height: 44px; min-width: 44px; justify-content: center; }
  .publish-bar .publish-state { flex: none; margin: 0; }
  .publish-bar .publish-state .form-hint { display: none; }
  .publish-bar #f-summary { display: none; }
  .publish-bar #f-required { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-size: .8rem; }
  #event-form .form-section-head { margin-bottom: 12px; }
  #event-form .form-section-head .form-hint:not(.lock-note) { font-size: .8rem; }
  #event-form .form-section { margin-top: 18px; padding-top: 18px; }
  #event-form .seg { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); width: 100%; }
  #event-form .seg-opt > span { display: flex; width: 100%; flex-direction: column; align-items: center; justify-content: center; gap: 2px; height: 100%; padding: 8px 6px; text-align: center; font-size: .8rem; }
  #event-form .seg-opt span .material-symbols-rounded { font-size: 20px; }
}

/* ---------- Calendar ---------- */
.agenda-price .material-symbols-rounded { font-size: 16px; color: var(--esn-green); }
.calendar-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 10px 14px;
  margin: 30px 0 14px;
}
.calendar-header h2 { font-size: 1.3rem; font-weight: 900; white-space: nowrap; }
.cal-title { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; min-width: 0; }
.cal-title .cal-view-pick { margin: 0; }
.cal-nav-buttons { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; position: relative; }
.calendar-grid {
  display: grid;
  /* minmax(0,1fr): a plain 1fr cannot shrink below a pill's nowrap min-content,
     so one long event title used to push the whole grid wider than the page */
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 6px;
  margin-bottom: 44px;
}
.cal-cell { min-width: 0; background: var(--card); border: 1px solid var(--border); border-radius: var(--r-sm); min-height: 104px; padding: 7px; font-size: .8rem; display: flex; flex-direction: column; gap: 4px; position: relative; }
.cal-cell .cal-event { max-width: 100%; }
.cal-dow {
  text-align: center;
  font-weight: 700;
  font-size: .75rem;
  text-transform: uppercase;
  letter-spacing: 1.2px;
  color: var(--muted);
  padding: 8px 0 4px;
}
html[data-theme="dark"] .cal-dow { color: #b9bcdc; }
.cal-cell.other-month { background: transparent; border-style: dashed; opacity: .45; }
html[data-theme="dark"] .cal-cell.other-month { opacity: .3; }
.cal-cell.today { border: 2px solid var(--esn-cyan); }
.cal-cell.weekend:not(.other-month) { background: color-mix(in srgb, var(--esn-cyan) 4%, var(--card)); }
.cal-daynum { font-weight: 700; color: var(--muted); font-size: .75rem; font-variant-numeric: tabular-nums; min-width: 22px; height: 22px; display: inline-flex; align-items: center; justify-content: center; align-self: flex-start; border-radius: 999px; }
/* Dark-mode calendar legibility: day numbers & weekday headers were too dim */
html[data-theme="dark"] .cal-daynum { color: var(--ink); }
/* 1.50.2: a light chip in the event's colour with its icon, the time, the
   name; a check when you have a ticket */
.cal-event {
  display: flex;
  align-items: center;
  gap: 4px;
  background: color-mix(in srgb, var(--accent, var(--esn-cyan)) 14%, var(--card));
  border-left: 3px solid var(--accent, var(--esn-cyan));
  border-radius: 6px;
  padding: 3px 6px 3px 4px;
  font-weight: 700;
  font-size: .75rem;
  line-height: 1.25;
  overflow: hidden;
  white-space: nowrap;
}
.cal-event .material-symbols-rounded { font-size: 15px; color: var(--accent, var(--esn-cyan)); flex: none; }
.cal-ev-time { flex: none; color: var(--muted); font-weight: 700; font-variant-numeric: tabular-nums; }
.cal-ev-time:empty { display: none; }
.cal-ev-t { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.cal-ev-going { margin-left: auto; display: inline-flex; flex: none; }
.cal-ev-going .material-symbols-rounded { color: var(--esn-green); }
.cal-event.cal-cancelled, .agenda-item.cal-cancelled { opacity: .55; }
.cal-event.cal-cancelled .cal-ev-t, .agenda-item.cal-cancelled .agenda-title { text-decoration: line-through; }
.cal-tag-chip .material-symbols-rounded { color: var(--accent); }
.cal-tag-chip.active .material-symbols-rounded { color: inherit; }
.cal-event:hover { text-decoration: none; opacity: .88; }
.cal-dots { display: none; }
/* Calendar by role (1.1.20): drafts dashed, meetings in ESN dark, a plus for the board */
.cal-event.cal-draft, .agenda-item.cal-draft { border: 1px dashed currentColor; opacity: .8; }
.cal-event.cal-draft { background: transparent; color: var(--magenta-text); }
.cal-event.cal-meeting { background: color-mix(in srgb, var(--esn-dark) 10%, var(--card)); }
.cal-cell > .cal-add, .agenda-date > .cal-add { border: 0; background: transparent; color: var(--muted); cursor: pointer; padding: 0; line-height: 1; display: inline-flex; align-items: center; justify-content: center; }
.cal-cell > .cal-add { position: absolute; border-radius: 50%; opacity: 0; transition: opacity var(--t-fast); width: 28px; height: 28px; top: 2px; right: 2px; }
.cal-cell:hover > .cal-add, .cal-cell:focus-within > .cal-add { opacity: 1; }
.cal-cell > .cal-add:hover, .agenda-date > .cal-add:hover { background: var(--esn-green); color: var(--on-bright); }
.agenda-date { display: flex; align-items: center; gap: 8px; position: relative; font-size: .75rem; font-weight: 700; text-transform: uppercase; letter-spacing: .8px; color: var(--muted); margin: 18px 0 8px; }
.agenda-date > .material-symbols-rounded { font-size: 17px; color: var(--accent-text); }
.agenda-rel { padding: 2px 8px; border-radius: 999px; background: var(--esn-cyan); color: var(--on-bright); letter-spacing: .4px; font-size: .75rem; }
.agenda-date > .cal-add-agenda { margin-left: auto; width: 24px; height: 24px; border-radius: 50%; border: 1px solid var(--border); }
.cal-plan { position: absolute; z-index: 20; background: var(--card); border: 1px solid var(--border); border-radius: var(--r-md); box-shadow: var(--shadow-pop); padding: 10px 12px; display: flex; flex-direction: column; gap: 4px; min-width: 190px; font-size: .9rem; }
.cal-plan a { display: flex; align-items: center; gap: 8px; padding: 6px 8px; border-radius: var(--r-sm); color: var(--ink); font-weight: 700; white-space: nowrap; }
.cal-plan a:hover { background: var(--bg); text-decoration: none; }
.calendar-header .cal-plan { right: 0; top: 100%; margin-top: 6px; }
.cal-cell > .cal-plan { right: 4px; top: 26px; }
.agenda-date .cal-plan { right: 0; top: 100%; text-transform: none; letter-spacing: 0; }
.cal-agenda { margin: 4px 0 40px; }
.agenda-item {
  display: flex;
  align-items: center;
  gap: 12px;
  background: var(--card);
  border: 1px solid var(--border);
  border-left: 4px solid var(--accent, var(--esn-cyan));
  border-radius: 12px;
  padding: 10px 12px;
  margin-bottom: 8px;
  color: var(--ink);
  touch-action: manipulation;
  -webkit-user-select: none;
  user-select: none;
}
.agenda-item:hover { text-decoration: none; }
.agenda-time { flex: none; width: 44px; font-weight: 700; font-size: .75rem; color: var(--muted); }
html[data-theme="dark"] .agenda-time { color: #b9bcdc; }
.agenda-time.agenda-date { width: auto; min-width: 118px; }
.agenda-time.sh-when { display: flex; flex-direction: column; align-items: center; line-height: 1.1; text-transform: uppercase; }  /* 1.78.7: My shifts: a date badge, not a date over three lines */
.sh-when b { font-size: 1.15rem; font-weight: 900; color: var(--ink); }
.agenda-title { flex: 1; min-width: 0; font-weight: 700; font-size: .9rem; overflow-wrap: anywhere; }
/* 1.50.2: the list view: an icon tile in the event's colour, then the name and a line with time and place */
.agenda-ico { flex: none; width: 40px; height: 40px; border-radius: 12px; display: inline-flex; align-items: center; justify-content: center; background: color-mix(in srgb, var(--accent, var(--esn-cyan)) 16%, var(--card)); color: var(--accent, var(--esn-cyan)); }
.agenda-ico .material-symbols-rounded { font-size: 22px; }
.ev-ico { flex: none; width: 36px; height: 36px; border-radius: 11px; display: inline-flex; align-items: center; justify-content: center; background: color-mix(in srgb, var(--accent, var(--esn-cyan)) 16%, var(--card)); color: var(--accent, var(--esn-cyan)); } /* 1.71.3: an event's icon in the team's lists */
.ev-ico .material-symbols-rounded { font-size: 20px; }
.ev-ico.sm { width: 28px; height: 28px; border-radius: 9px; }
.ev-ico.sm .material-symbols-rounded { font-size: 17px; }
.ev-ico-row { display: flex; align-items: center; gap: 10px; min-width: 0; }
.agenda-main { flex: 1; min-width: 0; display: grid; gap: 3px; }
.agenda-main .agenda-title { flex: none; }
.agenda-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 2px 12px; font-size: .8rem; color: var(--muted); font-weight: 600; min-width: 0; max-width: 100%; }  /* 1.68.1: a grid child shrinks, so the place line ellipsises instead of running off the card */
.agenda-pic { overflow: hidden; padding: 0; width: 64px; height: 48px; border-radius: 10px; background: var(--surface2); }  /* 1.68.1: the event's picture in the list, like the website calendar */
.agenda-pic img { width: 100%; height: 100%; object-fit: cover; display: block; }
.agenda-meta .material-symbols-rounded { font-size: 15px; vertical-align: -3px; margin-right: 2px; }
.agenda-place { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%; }
.agenda-price { font-weight: 900; font-size: .8rem; color: var(--esn-dark); }
html[data-theme="dark"] .agenda-price { color: var(--esn-cyan); }
.cal-event.cal-cont { opacity: 0.75; }  /* v0.99.9: Multi-day events in the calendar */
.agenda-item.cal-cont .agenda-time { color: var(--muted); }
/* Dark mode: calendar chips & agenda rows must not inherit the global
   dark link colour (cyan text on cyan office-hours chips = invisible) */
a.cal-event, html[data-theme="dark"] a.cal-event { color: var(--ink); }  /* v0.131; dark text on the light chips since 1.50.2 */
a.agenda-item, html[data-theme="dark"] a.agenda-item { color: var(--ink); }
.agenda-price.free { color: var(--green-text); }  /* 1.29.4: one system */
.cal-cell.today .cal-daynum { color: var(--on-bright); background: var(--esn-cyan); }
.agenda-date > .cal-add { min-width: 30px; min-height: 30px; }  /* 1.29.4: colour follow-ups */
@media (max-width: 820px) {
  /* Calendar on mobile: compact dot grid + tappable agenda below */
  .calendar-header { margin-top: 16px; }  /* Responsive */
  .calendar-header h2 { font-size: 1.15rem; }
  /* One tidy row of controls under the title - never wider than the screen */
  /* 1.78.7: a calmer phone calendar: the month and Today on one row, the view and Plan on the next, dots in the days */
  .cal-head2 { display: grid; grid-template-columns: minmax(0, 1fr) auto auto; grid-template-areas: "nav nav today" "view . plan"; align-items: center; gap: 8px; position: relative; }
  .cal-head2 .cal-nav { grid-area: nav; min-width: 0; }
  .cal-head2 .cal-nav-buttons { display: contents; }
  .cal-head2 .cal-today { grid-area: today; }
  .cal-head2 .cal-view-pick { grid-area: view; justify-self: start; }
  .cal-head2 .cal-add-head { grid-area: plan; }
  .cal-head2 a[href^="/board/studio"] { display: none; }
  .cal-head2 .btn { padding: 6px 12px; }
  .cal-head2 + p.form-hint { font-size: .75rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .cal-head2 ~ .filter-chips .chip { padding: 4px 10px; font-size: .8rem; }
  .agenda-date > .cal-add { display: none; }
  .cal-cell { min-height: 44px; padding: 5px 2px; align-items: center; gap: 4px; }
  .cal-cell.has-ev { cursor: pointer; }
  .cal-event { display: none; }
  .cal-cell > .cal-add { display: none; }
  /* the plus lives on the agenda day on a phone */
  .cal-dots { display: flex; flex-wrap: wrap; gap: 2px; justify-content: center; align-items: center; }
  .cal-dots { gap: 3px; }
  .cal-dots i { width: 8px; height: 8px; border-radius: 50%; display: inline-block; background: var(--accent); }
  .cal-dots i .material-symbols-rounded { display: none; }
  .cal-dots i.going { box-shadow: 0 0 0 2px var(--card), 0 0 0 3px var(--esn-green); }
  .cal-dots b { font-size: .75rem; color: var(--muted); }
  .cal-daynum { align-self: center; }
  .agenda-ico { width: 36px; height: 36px; }
  .agenda-ico.agenda-pic { width: 60px; height: 44px; }
  .calendar-grid { margin-bottom: 10px; gap: 4px; }
  .cal-daynum { font-size: .8rem; }
}

/* ---------- Event detail ---------- */
.ev-going, .ev-rate, .ev-shifts { font-size: .9rem; margin: 10px 0 0; }  /* 1.1.15: Settings markers */
.ev-series { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.event-detail {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  margin: 28px 0 44px;
  overflow: hidden;
}
.event-detail-banner {
  padding: 38px 36px;
  color: #fff;
  background: var(--esn-dark);
  border-bottom: 4px solid var(--accent, var(--esn-cyan));
}
.event-detail-banner.has-img { background-size: cover; background-position: center; }
.event-detail-body {
  padding: 30px 36px;
  display: grid;
  gap: 36px;
  grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr);
}
.event-info-list { list-style: none; display: flex; flex-direction: column; gap: 8px; margin: 0 0 18px; }
.event-info-list li { display: flex; gap: 14px; align-items: baseline; }
.event-info-list .ico { width: 22px; text-align: center; }
.info-label {
  flex: none;
  width: 82px;
  font-size: .75rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 1px;
  color: var(--muted);
}
.buy-box {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 22px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  height: fit-content;
}
.buy-box .price-tag { font-size: 1.45rem; }
.qty-row { display: flex; align-items: center; gap: 10px; }
.qty-row input {
  width: 72px;
  padding: 8px;
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  font-family: inherit;
  font-size: .95rem;
  text-align: center;
  background: var(--card);
  color: var(--ink);
}
/* Share and calendar: two buttons and a menu, not four buttons */
/* Event page action row: equal buttons, labels on one line, the menu centred under its button */
.cal-links { display: flex; flex-wrap: wrap; align-items: center; margin-top: 10px; gap: 8px; }
.buy-box select {
  transition: border-color var(--t-fast) ease, box-shadow var(--t-fast) ease;
}  /* v0.109.1: Design pass — playbook fundamentals */
.ev-friends { display: flex; align-items: center; gap: 6px; margin: 0 0 10px; font-size: .85rem; color: var(--muted); }  /* 1.17.0: ESN Passport 2.0 */
.ev-friends .av + .av { margin-left: -8px; }
.av-stack { display: inline-flex; align-items: center; flex-shrink: 0; }  /* 1.33.0: friends going */
.av-stack .av { border: 2px solid var(--card); box-sizing: content-box; transform: translateY(var(--lift, 0px)) scale(var(--pop, 1)); transition: transform var(--dur-avatar) var(--ease-settle); }  /* 1.78.16: the spring (app.js sets --lift and --pop) */
.av-stack .av:hover { z-index: 1; }
.av.av-more { background: var(--surface2); color: var(--ink); }  /* 1.78.16: "+3", the rest of a stack */
.av-stack .av + .av { margin-left: -7px; }
.event-meta .ev-friends { margin: 0; color: var(--accent-text); font-weight: 700; font-size: .8rem; }
.ev-friends-page { margin: 0 0 12px; font-weight: 700; color: var(--ink); }
.ev-friends-page .av-stack .av + .av { margin-left: -10px; }
/* the event page: the chosen type is visible on the select itself */
#opt-select.has-color { border-left: 8px solid var(--c); }  /* 1.19.0: ticket types with a colour */
.opt-chosen { display: flex; align-items: center; gap: 8px; margin: 6px 0 0; font-weight: 700; }
.ev-facts { gap: 10px; overflow-wrap: anywhere; }  /* 1.29.3: event page polish */
.ev-facts li { align-items: center; gap: 12px; font-size: .95rem; line-height: 1.35; }
.ev-facts li > span:last-child { min-width: 0; }
.info-label.info-ico {
  width: 32px; height: 32px; flex: none; border-radius: 9px; letter-spacing: 0;
  display: inline-flex; align-items: center; justify-content: center;
  background: color-mix(in srgb, var(--accent, var(--esn-cyan)) 14%, transparent);
  color: var(--accent, var(--esn-cyan));
}
.info-label.info-ico .material-symbols-rounded { font-size: 20px; }
.ev-facts a .material-symbols-rounded.mi-sm { font-size: 14px; vertical-align: -2px; margin-left: 2px; opacity: .7; }
.ev-facts .rel-t { vertical-align: 2px; }
.ev-facts .form-hint { font-size: .8rem; }
/* The board bar under the hero: one scrolling row, never a block of buttons */
.ev-admin-bar {
  display: flex; align-items: center; gap: 8px; padding: 12px 18px 0; overflow-x: auto; scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}
.ev-admin-bar::-webkit-scrollbar { display: none; }
.ev-admin-bar > * { flex: none; }
.ev-admin-k { display: inline-flex; align-items: center; gap: 4px; font-size: .75rem; font-weight: 800; text-transform: uppercase; letter-spacing: .5px; color: var(--muted); margin-right: 2px; }
.ev-admin-n { display: inline-block; min-width: 18px; padding: 0 5px; border-radius: 999px; background: var(--esn-cyan); color: var(--on-bright); font-size: .75rem; line-height: 18px; text-align: center; margin-left: 2px; }
/* The ticket box: badges stay small, the door part is flat inside it */
.buy-box > .badge { align-self: flex-start; }
.ev-door-price { margin: 0; font-size: 1rem; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.ev-door-price strong { font-size: 1.3rem; font-weight: 900; }
.ev-door-price .form-hint strong { font-size: .95rem; }
.ev-door-sub { margin: -6px 0 0; font-size: .85rem; color: var(--muted); }
.ev-door-sub strong { color: var(--ink); }
.ev-have { display: flex; align-items: center; gap: 8px; margin: 0; font-size: 1rem; flex-wrap: wrap; }
.ev-have-ic {
  width: 28px; height: 28px; border-radius: 50%; flex: none; display: inline-flex; align-items: center; justify-content: center;
  background: color-mix(in srgb, var(--esn-green) 18%, transparent); color: var(--esn-green);
}
.ev-have-ic.warn { background: color-mix(in srgb, var(--esn-orange) 18%, transparent); color: var(--esn-orange); }
.ev-have .form-hint { font-weight: 400; }
.ev-fine { margin: 0; font-size: .8rem; line-height: 1.5; }
.ev-fine .material-symbols-rounded.mi-sm { font-size: 14px; opacity: .8; vertical-align: -3px; }
.ev-fine .hint-i { vertical-align: -4px; margin-left: 2px; }
.buy-box .esncard-nudge { margin: 0; }
.cal-links .more-menu > summary { cursor: pointer; }
.cal-links .more-menu > summary .material-symbols-rounded:last-child { font-size: 16px; margin-left: -2px; opacity: .7; }
.cal-links > .btn, .cal-links > .more-menu > summary { white-space: nowrap; }  /* 1.29.4: sweep */
.cal-links .more-menu-list { left: 50%; right: auto; transform: translateX(-50%); min-width: 220px; }
.ev-foot { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; }
.ev-foot .ev-going { margin: 0; }
/* Dark mode: the accent-tinted icon tiles need a lighter ink, the accent
   colour itself (a saturated brand blue) sinks into the navy background */
html[data-theme="dark"] .info-label.info-ico {
  color: color-mix(in srgb, var(--accent, var(--esn-cyan)) 55%, #fff);
  background: color-mix(in srgb, var(--accent, var(--esn-cyan)) 30%, transparent);
}
.event-detail-banner .back-chip, html[data-theme="dark"] .event-detail-banner .back-chip { color: #dfe3ff; }  /* 1.29.4: one system */
.event-detail-banner .back-chip:hover { color: #fff; }
.event-detail-body > * { min-width: 0; }  /* 1.40.0: mobile polish from the September screenshots */
@media (min-width: 821px) {
  .buy-box { position: sticky; top: 84px; }
  .ev-admin-bar { padding: 14px 36px 0; }  /* 1.29.3: event page polish */
}
@media (max-width: 820px) {
  .event-detail-body { padding: 20px; gap: 18px; grid-template-columns: minmax(0, 1fr); }  /* Responsive */
  /* The ticket box comes right after When/Where, not after the map (1.1.11). */
  .event-detail-body > div:first-child { display: contents; }
  .event-detail-body > div:first-child > .event-info-list { order: 1; margin-bottom: 0; }
  .event-detail-body > .buy-box { order: 2; }
  .event-detail-body > div:first-child > .rich { order: 3; }
  .event-detail-body > div:first-child > #ev-extra { order: 3; }
  .event-detail-body > div:first-child > .cal-links { order: 4; }
  .event-detail-body > div:first-child > .map-wrap { order: 5; }
  .info-label { width: 70px; }
  .ev-admin-bar { mask-image: linear-gradient(90deg, #000 calc(100% - 28px), transparent); padding-right: 28px; }  /* 1.29.3: event page polish */
  html.has-back .event-detail-banner .back-chip { display: none; }
  .event-detail-banner { padding: 28px 20px 22px; }
  .event-detail { margin-top: 12px; }
  .cal-links { display: grid; grid-template-columns: repeat(3, 1fr); }  /* 1.29.4: sweep */
  .cal-links > .btn, .cal-links > .more-menu { width: 100%; }
  .cal-links > .more-menu > summary { width: 100%; justify-content: center; }
}
@media (max-width: 640px) {
  .info-label { width: 92px; }  /* 1.14.1: one button */
}
@media (max-width: 420px) {
  .cal-links > .btn, .cal-links > .more-menu > summary { padding-left: 6px; padding-right: 6px; }  /* 1.29.4: Headings */
}

/* ---------- Map embed ---------- */
/* Lazy map with a fallback (1.1.17) */
.map-lazy .map-load { display: flex; align-items: center; gap: 10px; width: 100%; min-height: 96px; padding: 14px; background: var(--bg); border: 1px dashed var(--border); border-radius: var(--r-md); color: var(--ink); font: inherit; text-align: left; cursor: pointer; }  /* 1.1.15: Settings markers */
.map-lazy .map-load .material-symbols-rounded { font-size: 28px; color: var(--esn-cyan); }
.map-wrap {
  margin-top: 18px;
  border-radius: var(--radius);
  overflow: hidden;
  border: 1px solid var(--border);
}
.map-embed { width: 100%; height: 260px; border: 0; display: block; }
@media (max-width: 820px) {
  .map-embed { height: 200px; }  /* Responsive */
}

/* ---------- Nationality map (admin) ---------- */
#nat-map svg { display: block; width: 100%; height: auto; }
#nat-map path.country { stroke: #fff; stroke-width: .5; }
#nat-map path.country:hover { stroke: var(--ink); stroke-width: 1; }
.map-tip {
  position: absolute;
  background: var(--ink);
  color: #fff;
  font-size: .8rem;
  font-weight: 700;
  padding: 5px 10px;
  border-radius: 6px;
  pointer-events: none;
  white-space: nowrap;
  z-index: 10;
  box-shadow: var(--shadow-pop);
}
.map-legend {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 8px;
  font-size: .75rem;
  color: var(--muted);
  font-weight: 700;
}
.map-grad {
  width: 140px;
  height: 8px;
  border-radius: 4px;
  border: 1px solid var(--border);
}
html[data-theme="dark"] #nat-map path.country { stroke: #12132a; }  /* v1.5.0: audit */

/* ---------- Kiosk ---------- */
.kiosk-result {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  color: #fff;
  padding: 20px;
  z-index: 5;
}
.kiosk-result h3 { font-size: 1.45rem; margin-bottom: 4px; }
.kiosk-result p { font-size: .95rem; }
.kiosk-ok { background: rgba(58, 148, 34, .93); }
.kiosk-warn { background: rgba(216, 128, 14, .94); }
.kiosk-bad { background: rgba(198, 27, 87, .94); }

/* ---------- The globe (1.12.0) ---------- */
.globe-page { max-width: none; margin: 0; }
.globe-head { margin-bottom: 10px; }
/* 1.76.0: the numbers as tiles, the filters in labelled rows, the views and the zoom in one bar on the card */
.globe-strip { display: grid; grid-template-columns: repeat(auto-fit, minmax(8.5rem, 1fr)); gap: 8px; font-size: .8rem; color: var(--muted); }
.globe-stat { display: flex; flex-direction: column; gap: 2px; background: var(--surface2); border-radius: var(--r-md); padding: 10px 12px; line-height: 1.3; }
.globe-stat b { font-size: 1.3rem; font-weight: 900; font-variant-numeric: tabular-nums; color: var(--accent-text); }
.globe-when { grid-column: 1 / -1; font-size: .75rem; margin: 0; }
.globe-tools { display: flex; flex-direction: column; gap: 8px; margin: 0 0 12px; }
.globe-frow { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 10px; }
.globe-flbl { font-size: .75rem; font-weight: 800; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); min-width: 3.2rem; }
.globe-bar { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px; padding: 10px 12px; border-bottom: 1px solid var(--border); }
.globe-views { display: inline-flex; flex-wrap: wrap; gap: 6px; }
.globe-bar-sub { flex: 1 0 100%; display: flex; align-items: center; flex-wrap: wrap; gap: 8px 10px; }
.globe-tools .filter-chips { margin-right: 4px; }
.globe-grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: 14px; align-items: start; position: relative; }
/* From 1000px up the side panel floats over the stage (1.15.0 block at the end). */
.globe-card { overflow: hidden; }
.globe-stage { position: relative; border-radius: 0; overflow: hidden; background: radial-gradient(120% 90% at 50% 0%, var(--globe-bg-0), var(--globe-bg-1) 70%); }
.globe-box { width: 100%; margin: 0 auto; aspect-ratio: 1 / 1; max-height: min(78vh, 760px); touch-action: none; user-select: none; -webkit-user-select: none; }
.globe-svg { display: block; width: 100%; height: 100%; cursor: grab; }
.globe-svg:active { cursor: grabbing; }
.globe-grat { fill: none; stroke: var(--globe-grat); stroke-width: .5; }
.globe-rim { fill: none; stroke: var(--globe-rim); stroke-width: 1; }
.globe-land { stroke: var(--globe-line); stroke-width: .45; transition: fill var(--t-slow); }
.globe-land.has { cursor: pointer; }
.globe-land.has:hover { filter: brightness(1.15); }
.globe-land.mine { stroke: var(--esn-green); stroke-width: 1.5; }
.globe-land.sel { stroke: var(--esn-magenta); stroke-width: 1.8; }
.globe-svg.zoomed .globe-land { fill: var(--globe-land-zoomed); stroke: none; cursor: default; pointer-events: none; }
.globe-svg.zoomed .globe-grat, .globe-svg.zoomed .globe-rim { display: none; }
.globe-arc { fill: none; stroke: var(--globe-arc); stroke-width: calc(var(--w, 1) * 1.3px); stroke-linecap: round; stroke-dasharray: 6 8; pointer-events: none; transition: opacity var(--t-slow); }
.globe-arcs.has-sel .globe-arc { opacity: .35; }
.globe-arcs.has-sel .globe-arc.sel { opacity: 1; stroke: var(--globe-arc-sel); stroke-width: 2px; }
.globe-beacon .beacon-dot { fill: var(--esn-green); stroke: #fff; stroke-width: 1.2; }
.globe-beacon .beacon-pulse { fill: none; stroke: var(--esn-green); stroke-width: 1.2; opacity: .7; transform-box: fill-box; transform-origin: center; }
.globe-beacon .beacon-lbl { fill: var(--globe-lbl); font-size: 11px; font-weight: 800; letter-spacing: .04em; paint-order: stroke; stroke: var(--globe-halo); stroke-width: 3px; }
.globe-ripple { fill: none; stroke: var(--globe-arc-sel); stroke-width: 2; vector-effect: non-scaling-stroke; opacity: .9; transform-box: fill-box; transform-origin: center; pointer-events: none; }
.pt-dot { fill: var(--globe-pt); stroke: var(--globe-halo); stroke-width: 1.2; cursor: pointer; }
.pt-pulse { fill: none; stroke: var(--globe-pt); stroke-width: 1.2; opacity: .6; pointer-events: none; transform-box: fill-box; transform-origin: center; }
.pt-lbl { display: none; fill: var(--globe-lbl); font-size: 11px; font-weight: 700; paint-order: stroke; stroke: var(--globe-halo); stroke-width: 3px; pointer-events: none; }
.pt.focus .pt-lbl, .pt:hover .pt-lbl, .globe-svg.zoomed-in .pt-lbl { display: block; }
.globe-zoom { display: inline-flex; gap: 4px; margin-left: auto; }
.globe-zoom .btn { padding-left: 8px; padding-right: 8px; }
.pt.focus .pt-dot { stroke: var(--globe-focus); stroke-width: 2; }
/* The street map fades in over the sphere once the dive has landed. */
.ghent-map { position: absolute; inset: 0; opacity: 0; transition: opacity .35s ease; background: var(--map-bg); }
.ghent-map.show { opacity: 1; }
.ghent-map .leaflet-popup-content { font: inherit; font-size: .9rem; }
.ghent-map .leaflet-popup-content a { color: var(--esn-dark); font-weight: 700; }
.globe-legend { display: flex; align-items: center; flex-wrap: wrap; gap: 8px 14px; margin: 8px 12px 0; font-size: .75rem; color: var(--muted); }
.globe-legend .map-legend { margin: 0; }
.globe-grad { background: linear-gradient(90deg, var(--globe-lo), var(--globe-hi)); }
.globe-hint { flex: 1; }
.globe-key { display: inline-flex; align-items: center; gap: 5px; }
.globe-dot { width: 9px; height: 9px; border-radius: 50%; display: inline-block; border: 1.5px solid #fff; box-shadow: 0 0 0 1px rgba(0, 0, 0, .15); }
.globe-dot.city { background: #35c6ee; }
.globe-dot.venue { background: var(--pin-venue); }
.globe-side { display: flex; flex-direction: column; gap: 12px; }
.globe-panel { min-height: 92px; }
.globe-title { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 4px; }
.globe-country { font-size: 1.15rem; font-weight: 900; display: block; margin-bottom: 8px; }
.globe-stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; }
.globe-stats.three { grid-template-columns: repeat(3, 1fr); }
.globe-stats.two { grid-template-columns: repeat(2, 1fr); }
.globe-stats.one { grid-template-columns: minmax(0, 1fr); }
.globe-stats > div { background: var(--surface2); border-radius: 10px; padding: 8px 6px; text-align: center; display: flex; flex-direction: column; }
.globe-stats b { font-size: 1.15rem; font-weight: 900; font-variant-numeric: tabular-nums; color: var(--esn-dark); }
html[data-theme="dark"] .globe-stats b { color: var(--esn-cyan); }
.globe-stats span { font-size: .75rem; color: var(--muted); }
.globe-top { list-style: none; margin: 4px 0 0; padding: 0; counter-reset: gt; }
.globe-top li { counter-increment: gt; }
.globe-pick { width: 100%; display: flex; align-items: center; gap: 8px; background: none; border: 0; padding: 7px 4px; font: inherit; color: var(--ink); text-align: left; border-radius: var(--r-sm); cursor: pointer; }
.globe-top .globe-pick::before { content: counter(gt); width: 22px; font-size: .75rem; font-weight: 800; color: var(--cyan-text); }
.globe-pick:hover, .globe-pt:hover, .globe-pt.on { background: var(--surface2); }
.globe-pick .globe-n { margin-left: auto; font-weight: 800; font-variant-numeric: tabular-nums; }
.globe-people { margin-top: 10px; border-top: 1px solid var(--border); padding-top: 8px; }
.globe-list { list-style: none; margin: 0; padding: 0; max-height: 320px; overflow: auto; display: flex; flex-direction: column; gap: 4px; }
.globe-list li { display: flex; align-items: center; gap: 8px; }
.globe-list .badge { margin-left: auto; }
.globe-list.ghent { max-height: 220px; }
.globe-pt { width: 100%; display: flex; align-items: center; gap: 8px; background: none; border: 0; padding: 6px 6px; font: inherit; color: var(--ink); text-align: left; border-radius: var(--r-sm); cursor: pointer; }
.globe-pt small { margin-left: auto; color: var(--muted); font-size: .75rem; }
.globe-lists { display: grid; grid-template-columns: minmax(0, 1fr); gap: 12px; margin-top: 10px; }
.globe-more { display: grid; grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr)); gap: 14px; align-items: start; }  /* 1.72.0: More about us, under the globe */
.globe-about .viz-bars { margin-top: 8px; }
.globe-about .vb-lbl { white-space: normal; overflow-wrap: anywhere; line-height: 1.25; }
.chart-lbl { font-size: 11px; fill: var(--muted); font-family: inherit; }
.chart-val { font-size: 11px; font-weight: 700; fill: var(--ink); font-family: inherit; }
/* The stage is wider than it is tall on a desk, so the sphere gets the room
   the side panel does not take; on a phone it stays square. The panel floats
   over the right of the stage from 1000px and scrolls inside its own height,
   which viewGlobe writes into --stage-h. */
.globe-stage .globe-box { margin: 0; }  /* 1.15.0: colours per category */
/* The globe card has no padding: the stage runs edge to edge (declared here to win over .form-card). */
.globe-card.form-card { padding: 0 0 10px; }
.globe-tools .filter-chips + .filter-chips { margin-left: 2px; }
.globe-tools .chip { padding: 6px 11px; }
html[data-theme="dark"] .leaflet-popup-content-wrapper, html[data-theme="dark"] .leaflet-popup-tip { background: var(--card); color: var(--ink); }
html[data-theme="dark"] .leaflet-bar a { background: var(--card); color: var(--ink); border-color: var(--border); }
html[data-theme="dark"] .leaflet-control-attribution { background: rgba(20, 22, 40, .8); color: var(--muted); }
/* leaflet.css loads after this sheet, so its #ddd container needs beating. */
.ghent-map.leaflet-container { background: var(--map-bg); }
.globe-dot.partner { background: var(--c, var(--cat-bar)); }
@media (min-width: 1000px) {
  .globe-box { aspect-ratio: 16 / 10; }
  .globe-side { position: absolute; top: calc(var(--bar-h, 0px) + 12px); right: 12px; width: 300px; max-height: calc(var(--stage-h, 600px) - 24px); overflow: auto; z-index: 2; gap: 10px; scrollbar-width: thin; }
  .globe-side > .form-card { background: color-mix(in srgb, var(--card) 94%, transparent); box-shadow: var(--shadow-lg); margin: 0; flex: none; }
  .globe-card { padding: 0 0 10px; }
}
@media (max-width: 640px) {
  .globe-legend .globe-hint { flex: 1 0 100%; }
}
@media (prefers-reduced-motion: no-preference) {
  .globe-arc { animation: arc-flow 1.6s linear infinite; }
  .globe-beacon .beacon-pulse { animation: pt-pulse 2.2s ease-out infinite; }
  .globe-ripple { animation: globe-ripple .9s ease-out forwards; }
  .pt-pulse { animation: pt-pulse 2.6s ease-out infinite; }
  .pt.focus .pt-pulse { animation-duration: 1.2s; }
}

/* ---------- FAQ ---------- */
.faq-wrap { max-width: var(--w-read); margin-bottom: 44px; }
.faq-list {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  overflow: hidden;
}
.faq-item { border-bottom: 1px solid var(--border); }
.faq-item:last-child { border-bottom: none; }
.faq-item summary {
  padding: 14px 18px;
  font-weight: 700;
  font-size: .9rem;
  cursor: pointer;
  list-style: none;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
}
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary::after {
  content: "+";
  font-size: 1.15rem;
  color: var(--muted);
  flex: none;
}
.faq-item[open] summary::after { content: "–"; }
.faq-item summary:hover { background: var(--hover); }
.faq-a {
  padding: 0 18px 16px;
  font-size: .9rem;
  color: var(--ink);
}
.faq-a code {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 1px 5px;
  font-size: .82em;
}

/* ---------- Proof-of-exchange preview (admin) ---------- */
.proof-details summary {
  cursor: pointer;
  color: var(--accent-text);
  font-weight: 700;
  font-size: .8rem;
  list-style: none;
}
.proof-details summary::-webkit-details-marker { display: none; }
.proof-details[open] summary { margin-bottom: 6px; }
.proof-details img {
  max-width: 260px;
  max-height: 340px;
  border-radius: var(--r-sm);
  border: 1px solid var(--border);
  display: block;
}

/* ---------- Ticket type rows (admin form) ---------- */
.option-row {
  display: grid;
  grid-template-columns: 1fr 90px 90px 70px 118px 40px;
  gap: 8px;
  margin-bottom: 8px;
}
.option-row input {
  min-width: 0;
  width: 100%;
  padding: 8px 10px;
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  font-family: inherit;
  font-size: .9rem;
  background: var(--card);
  color: var(--ink);
}
.option-row .opt-color, .option-row select { min-width: 0; width: 100%; padding: 8px 10px; border: 1px solid var(--border); border-radius: var(--r-sm); background: var(--card); color: var(--ink); font: inherit; }  /* 1.19.0: ticket types with a colour */
@media (max-width: 820px) {
  .option-row {
    grid-template-columns: 1fr 1fr 1fr 44px;
    padding: 8px 0 10px;
    border-bottom: 1px dashed var(--border);
  }  /* Responsive */
  .option-row .opt-name { grid-column: 1 / -1; }
  .option-row .opt-color { grid-column: 1 / 4; }
}

/* ---------- Board meetings: attendance + to-dos ---------- */
.att-list, .todo-list { list-style: none; margin: 0; padding: 0; }
.att-row {
  display: flex; align-items: center; justify-content: space-between;
  gap: 10px; flex-wrap: wrap; padding: 8px 0; border-bottom: 1px solid var(--border);
}
.att-row:last-child { border-bottom: none; }
.att-name { min-width: 0; }
.att-chips { display: flex; gap: 6px; flex-wrap: wrap; }
.att-chip { padding: 3px 9px; font-size: .7rem; touch-action: manipulation; -webkit-user-select: none; user-select: none; min-height: 30px; }
.todo-row { display: flex; align-items: flex-start; gap: 10px; padding: 7px 0; border-bottom: 1px solid var(--border); }
.todo-row:last-child { border-bottom: none; }
.todo-row.done .todo-text { color: var(--muted); }
.todo-row input[type="checkbox"] { margin-top: 3px; accent-color: var(--esn-green); flex-shrink: 0; width: 20px; height: 20px; }
.todo-text { flex: 1; font-size: .9rem; }
.ev-note-row td { padding-top: 0 !important; border-top: none !important; }
/* Board meeting page (1.1.12) */
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; }
.mtg-ta {
  width: 100%; min-height: 4.4em; font-family: inherit; font-size: .9rem; line-height: 1.45; padding: 10px 12px;
  border: 1px solid var(--border); border-radius: var(--r-sm); background: var(--card); color: var(--ink);
  resize: vertical; overflow: hidden; transition: background .6s;
}  /* 1.23.1: Crumb */
.mtg-ta.mtg-updated { background: color-mix(in srgb, var(--esn-cyan) 14%, var(--card)); }
.att-summary { margin: 0 0 8px; font-size: .85rem; font-weight: 700; color: var(--ink); }
.att-chip.active::after { content: " ✓"; }
.mtg-toolbar { position: relative; z-index: 5; }
.todo-row.mine { background: rgba(122, 193, 67, .08); margin: 0 -8px; padding-left: 8px; padding-right: 8px; border-radius: var(--r-sm); }  /* v0.137: Board to-dos */
.fmt-bar { display: flex; flex-wrap: wrap; margin: 0 0 4px; gap: 6px; }  /* 1.32.0: minutes formatting bar */
.fmt-btn { min-width: 30px; height: 30px; padding: 0 6px; border: 1px solid var(--border); border-radius: var(--r-sm); background: var(--surface2); color: var(--muted); cursor: pointer; display: inline-flex; align-items: center; justify-content: center; }
.fmt-btn:hover, .fmt-btn:focus-visible { color: var(--accent-text); border-color: var(--esn-cyan); background: var(--card); }
.fmt-btn .material-symbols-rounded { font-size: 20px; }
.att-row .att-x, .doc-x { margin-left: 6px; border: 1px solid var(--border); border-radius: 50%; background: var(--surface2); color: var(--muted); cursor: pointer; display: inline-flex; align-items: center; justify-content: center; vertical-align: middle; width: 30px; height: 30px; }
.att-row .att-x:hover, .doc-x:hover { color: var(--danger); border-color: var(--danger); }
.att-row.att-guest .att-name { border-left: 3px solid var(--esn-cyan); padding-left: 8px; }
.att-avatars { display: inline-flex; align-items: center; }
.att-avatars .av { margin-right: -6px; border: 2px solid var(--card); }
.att-avatars .av-more { background: var(--surface2); color: var(--muted); font-size: .75rem; }
.att-avatars small { margin-left: 12px; color: var(--muted); }
.mtg-jump { display: flex; gap: 6px; flex-wrap: wrap; margin: 0 0 14px; }
.mtg-jump a { display: inline-flex; align-items: center; gap: 4px; padding: 6px 10px; border: 1px solid var(--border); border-radius: 999px; background: var(--card); color: var(--esn-dark); font-size: .8rem; font-weight: 700; text-decoration: none; min-height: 30px; }
.mtg-jump a:hover { border-color: var(--esn-cyan); }
.mtg-jump a b { background: var(--esn-cyan); color: var(--on-bright, #12142a); border-radius: 999px; padding: 0 6px; font-size: .7rem; }
.doc-list { list-style: none; margin: 0; padding: 0; }
.doc-row { display: flex; align-items: center; gap: 8px; padding: 8px 0; border-bottom: 1px solid var(--border); }
.doc-row:last-child { border-bottom: none; }
.doc-link { display: inline-flex; align-items: center; gap: 8px; flex: 1; min-width: 0; text-decoration: none; color: var(--text); }
.doc-link .doc-title { font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.doc-link small { white-space: nowrap; }
.doc-link:hover .doc-title { color: var(--esn-cyan-text, var(--esn-dark)); text-decoration: underline; }
@media (max-width: 640px) {
  .mtg-toolbar .more-menu { flex: 0 0 auto; }
}
@media (max-width: 600px) {
  .att-row { flex-wrap: wrap; }  /* 1.32.0: board pages measured for the first time */
  .att-chips { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 6px; width: 100%; margin-top: 6px; }
  .att-chip { padding: 3px 4px; justify-content: center; text-align: center; white-space: nowrap; }
}

/* ---------- Shiftlists ---------- */
.slot-group > .material-symbols-rounded { color: var(--muted); }
.shift-event-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 10px; margin-bottom: 10px; flex-wrap: wrap; min-width: 0; overflow-wrap: anywhere; }
.shift-row { padding: 10px 0; border-top: 1px solid var(--border); min-width: 0; overflow-wrap: anywhere; }  /* 1.52.0: a long shift name or link wraps */
.form-card > .shift-row:first-of-type { border-top: none; }
.shift-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.shift-slots { flex-wrap: wrap; margin: 6px 0; display: flex; flex-direction: column; gap: 8px; margin-top: 10px; }
.slot-group { display: inline-flex; align-items: center; gap: 5px; flex-wrap: wrap; }
.slot-chip {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 2px 10px 2px 3px; border-radius: 999px;
  font-size: .75rem; font-weight: 700; background: var(--surface2); color: var(--ink);
  border: 1px solid var(--border); max-width: 100%;
}
.slot-chip .person-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.slot-chip.board { border-color: var(--esn-dark); }
html[data-theme="dark"] .slot-chip.board { border-color: #4d54d8; }
.slot-open { font-family: inherit; display: inline-flex; align-items: center; gap: 2px; border: 1px dashed var(--esn-cyan); color: var(--esn-cyan); background: transparent; border-radius: 999px; padding: 5px 12px; font-size: .85rem; font-weight: 700; cursor: pointer; min-height: 34px;
}
button.slot-join {
  border-color: var(--esn-green); color: var(--esn-green);
  font-weight: 700; cursor: pointer;
  transition: background var(--t-fast) ease, color var(--t-fast) ease;
}
button.slot-join:hover { background: var(--esn-green); color: var(--on-bright); }
button.slot-join[data-role="board"]:hover { background: var(--esn-cyan); color: var(--on-bright); }
.shift-actions { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; margin-top: 4px; }
/* Account: who am I */
.account-role { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin: 4px 0 14px; }
.slot-chip.me { border-color: var(--esn-green); }
.shift-time, .shift-fill { display: inline-flex; align-items: center; gap: 3px; font-size: .8rem; color: var(--muted); font-weight: 700; }  /* Shift cards (team view */
.slot-group small { display: block; font-size: .75rem; text-transform: uppercase; letter-spacing: .4px; color: var(--muted); font-weight: 700; margin-bottom: 4px; }
.slot-open:hover { background: rgba(0, 174, 239, .1); }
.slot-open.muted { border-color: var(--border); color: var(--muted); cursor: default; }
button.slot-join.slot-open { color: var(--green-text); }  /* 1.29.4: one system */
button.slot-join[data-role="board"] { color: var(--accent-text); border-color: var(--accent-text); }

/* ---------- Organigram (Team tab, real tree since v0.120) ---------- */
.orgc { display: flex; flex-direction: column; align-items: center; margin: 8px 0 4px; }
.orgc-node {
  background: var(--card);
  border: 1px solid var(--border);
  border-top: 3px solid var(--accent, var(--esn-dark));
  border-radius: var(--r-md);
  padding: 12px 14px 11px;
  max-width: 360px;
  min-width: 240px;
  text-align: left;
  box-shadow: 0 1px 3px rgba(0, 0, 0, .06);
}
.orgc-head { display: flex; align-items: center; gap: 7px; }
.orgc-head strong { font-size: .9rem; }
.orgc-head .material-symbols-rounded { color: var(--accent, var(--esn-dark)); font-size: 20px; }
.orgc-n {
  margin-left: auto; min-width: 22px; height: 22px; padding: 0 6px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 999px; background: var(--accent, var(--esn-dark)); color: #fff;
  font-size: .75rem; font-weight: 900;
}
.orgc-people { display: flex; flex-wrap: wrap; gap: 6px; margin: 10px 0 8px; }
.orgp {
  display: inline-flex; align-items: center; gap: 7px; min-width: 0;
  padding: 4px 10px 4px 4px; border-radius: 999px;
  background: var(--surface2); border: 1px solid var(--border);
  color: var(--ink); text-decoration: none; max-width: 100%;
}
.orgp:hover, .orgp:focus-visible { border-color: var(--accent, var(--esn-cyan)); text-decoration: none; }
.orgp-txt { display: flex; flex-direction: column; min-width: 0; line-height: 1.15; }
.orgp-txt b { font-size: .8rem; font-weight: 800; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.orgp-txt small { font-size: .75rem; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.orgc-empty { font-size: .8rem; color: var(--muted); margin: 10px 0 8px; font-style: italic; }
.orgc-tail { margin: 0 0 8px; font-size: .8rem; }
.orgc-tail a { display: inline-flex; align-items: center; gap: 4px; }
.orgc-mgmt { border-top-width: 4px; }
.orgc-dashed { border-style: dashed; border-top-style: solid; }
.orgc-stem { width: 2px; height: 18px; background: var(--border); }
.orgc-stem-dashed { background: transparent; border-left: 2px dashed var(--border); }
.orgc-row { display: flex; gap: 34px; align-items: flex-start; justify-content: center; flex-wrap: wrap; position: relative; padding-top: 18px; }
.orgc-row::before { content: ""; position: absolute; top: 0; left: 22%; right: 22%; height: 2px; background: var(--border); }
.orgc-branch { display: flex; flex-direction: column; align-items: center; position: relative; gap: 0; }
.orgc-branch::before { content: ""; position: absolute; top: -18px; width: 2px; height: 18px; background: var(--border); }
@media (max-width: 700px) {
  .orgc-node { max-width: 100%; min-width: 0; width: 100%; }
  .orgc-branch { gap: 14px; width: 100%; }
  .orgc-stem { display: none; }
  .orgc-row { gap: 18px; padding-top: 8px; }  /* 1.1.38: What each role can do */
  .orgc-row::before, .orgc-branch::before { display: none; }
}

/* ---------- What each role can do (1.1.38) ---------- */
/* max-width is ignored on table cells in auto layout, so the columns have
   to be shared out explicitly - otherwise every column took its content's
   width and dragged the whole page sideways. */
.matrix { font-size: .8rem; table-layout: fixed; width: 100%; }
.matrix thead th { vertical-align: bottom; white-space: normal; }
/* on a phone the rows are cards */
.matrix td { overflow-wrap: anywhere; }
.matrix thead th small { display: block; font-weight: 500; color: var(--muted); font-size: .75rem; margin-top: 2px; text-transform: none; letter-spacing: 0; white-space: normal; }
.matrix tbody th { text-align: left; white-space: normal; text-transform: none; letter-spacing: 0; }
.matrix tbody th small { display: block; font-weight: 500; color: var(--muted); font-size: .75rem; white-space: normal; text-transform: none; letter-spacing: 0; margin-top: 2px; }
.mx-role { font-weight: 800; }
.mx { display: inline-flex; align-items: center; gap: 4px; font-weight: 700; font-size: .75rem; }
/* The icon already says yes or no in green and red; the word stays for
   screen readers so the table is not colour-only. */
.mx i { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.mx .material-symbols-rounded { font-size: 20px; }
.mx.yes { color: var(--esn-green); }
.mx.no { color: var(--muted); }
.mx.no .material-symbols-rounded { color: var(--danger); }
.mx.part { color: var(--muted); background: var(--surface2); border: 1px solid var(--border); border-radius: 999px; padding: 2px 9px; font-size: .7rem; }
/* Keep the matrix inside its card at every width. */
.matrix-wrap { max-width: 100%; }
.roles-grid { grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); }  /* 1.40.0: View as */
.role-can { list-style: none; margin: 0; padding: 0; display: grid; gap: 4px; font-size: .85rem; }
.role-can li { display: flex; align-items: flex-start; gap: 6px; }
.role-can li.yes .material-symbols-rounded { color: var(--esn-green); }
.role-can li.no { color: var(--muted); }
.role-can li.no .material-symbols-rounded { color: var(--danger); }
.role-can li.part .material-symbols-rounded { color: var(--esn-orange); }
@media (min-width: 821px) {
  .matrix th, .matrix td { padding-left: 10px; padding-right: 10px; }
  .matrix th:first-child { width: 23%; }
}
@media (max-width: 820px) {
  .matrix { table-layout: auto; }  /* Responsive */
}

/* ---------- Admin ---------- */
.admin-tabs { display: flex; gap: 0; margin: 0 0 22px; border-bottom: 1px solid var(--border); overflow-x: auto; scrollbar-width: none; }
#app > .admin-tabs:first-child { margin-top: 16px; }  /* 1.78.9: a page that starts with its tabs (Visuals, Terminal) keeps room under the top bar */
.admin-tabs::-webkit-scrollbar { display: none; }
/* 1.78.6: a row that can still scroll to the right fades at that edge (wireScrollRows sets the attributes), so a hidden tab is noticed */
[data-scroll]:not([data-scroll-end]) { -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 44px), rgba(0, 0, 0, .12)); mask-image: linear-gradient(to right, #000 calc(100% - 44px), rgba(0, 0, 0, .12)); }
/* 1.51.0: the tabs are links (Admin and Board alike) */
.admin-tabs > a { display: inline-flex; align-items: center; gap: 4px; white-space: nowrap; padding: 10px 18px; font-weight: 700; font-size: .85rem; color: var(--muted); border-bottom: 3px solid transparent; margin-bottom: -1px; text-decoration: none; touch-action: manipulation; -webkit-user-select: none; user-select: none; }
.admin-tabs > a:hover { color: var(--ink); text-decoration: none; }
.admin-tabs > a.active { color: var(--esn-dark); border-bottom-color: var(--esn-dark); }
html[data-theme="dark"] .admin-tabs > a.active { color: var(--esn-cyan); border-bottom-color: var(--esn-cyan); }
.admin-tabs > a .material-symbols-rounded { font-size: 16px; opacity: .85; }
@media (max-width: 700px) {
  /* one scrolling row of pills on a phone: no orphan tab on a second line,
     whatever the number of tabs the role gets */
  .admin-tabs { gap: 6px; border-bottom: none; margin: 0 -16px 16px; padding: 9px 16px 4px; scroll-snap-type: x proximity; scroll-padding-inline: 16px; }  /* 1.78.17: room above for the corner numbers */  /* 1.58.0: the first tab snaps to the padding, not the screen edge */
  .admin-tabs > a { position: relative; flex: none; padding: 8px 12px; border: 1px solid var(--border); border-radius: 999px; background: var(--card); margin-bottom: 0; font-size: .8rem; scroll-snap-align: start; }
  .admin-tabs > a:has(.tab-badge:not(.hidden)) { border-color: color-mix(in srgb, var(--magenta-deep) 55%, var(--border)); background: color-mix(in srgb, var(--magenta-deep) 7%, var(--card)); color: var(--ink); }  /* 1.78.17: the owner's "the tabs with a number don't stand out" */
  .admin-tabs .tab-badge { position: absolute; top: -8px; right: -4px; margin: 0; box-shadow: 0 0 0 2px var(--bg); }
  .admin-tabs > a.active { border-color: var(--esn-dark); background: var(--esn-dark); color: #fff; }
  html[data-theme="dark"] .admin-tabs > a.active { background: var(--esn-cyan); border-color: var(--esn-cyan); color: var(--on-bright); }
}

/* ---------- Reviews and ideas (1.11.2) ---------- */
.rv-head { display: flex; gap: 20px; flex-wrap: wrap; align-items: flex-start; }
.rv-avg { display: flex; flex-direction: column; gap: 2px; min-width: 120px; }
.rv-avg strong { font-size: 2rem; line-height: 1; }
.rv-stars { letter-spacing: 1px; font-size: .95rem; white-space: nowrap; color: var(--orange-text); }
.rv-stars .rv-off { color: var(--border); }
.rv-dist { flex: 1; min-width: 200px; display: grid; gap: 4px; }
.rv-bar { display: grid; grid-template-columns: 14px 1fr 28px; align-items: center; gap: 8px; font-size: .8rem; color: var(--muted); }
.rv-bar i { display: block; height: 8px; border-radius: 4px; background: var(--surface2); overflow: hidden; }
.rv-bar i b { display: block; height: 100%; background: var(--esn-orange); border-radius: 4px; }
.rv-bar small { text-align: right; font-variant-numeric: tabular-nums; }
.rv-toggle { display: inline-flex; align-items: center; gap: 6px; font-size: .85rem; color: var(--muted); cursor: pointer; }
.rv-list, .ideas-list { list-style: none; margin: 8px 0 0; padding: 0; }
.rv-item, .ideas-list li { padding: 10px 0; border-top: 1px solid var(--border); }
.rv-list.text-only .rv-item:not(.has-text) { display: none; }
.rv-who { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 4px; }
.rv-who time { margin-left: auto; }
.rv-body p, .ideas-list p { margin: 4px 0 0; font-size: .9rem; white-space: pre-wrap; }
.ideas-list li.used p { color: var(--muted); text-decoration: line-through; }
.ideas-list .rv-toggle { margin-top: 6px; }
.rv-chip { display: inline-flex; align-items: center; gap: 3px; margin-left: 6px; padding: 1px 7px; border-radius: 999px; background: rgba(244, 123, 32, .12); color: var(--orange-text); font-weight: 800; font-size: .8rem; text-decoration: none; white-space: nowrap; }
.rv-chip small { font-weight: 600; opacity: .8; }

/* ---------- ESNcard nudges (1.11.2) ---------- */
.esncard-nudge { display: flex; gap: 8px; align-items: flex-start; margin: 0 0 10px; padding: 10px 12px; border-radius: var(--r-md); background: rgba(0, 174, 239, .10); border: 1px solid rgba(0, 174, 239, .35); font-size: .88rem; }
.esncard-nudge .material-symbols-rounded { color: var(--esn-cyan); flex: none; margin-top: 2px; }
.esncard-nudge a { font-weight: 800; color: var(--magenta-text); }
.esncard-line { display: flex; align-items: flex-start; gap: 6px; margin-top: 8px; font-size: .82rem; color: var(--muted); line-height: 1.45; }
.esncard-line > span { flex: 1; min-width: 0; }
.esncard-line .material-symbols-rounded { font-size: 18px; color: var(--esn-cyan); flex: none; }
.esncard-line a { font-weight: 800; text-decoration: none; white-space: nowrap; color: var(--magenta-text); }
.esncard-line-x { flex: none; margin: -4px 0 0; background: none; border: 0; padding: 5px 8px; min-width: 24px; min-height: 24px; color: var(--muted); font-size: .8rem; line-height: 1; cursor: pointer; opacity: .7; border-radius: 6px; }
.esncard-line-x:hover { opacity: 1; background: var(--surface2); }

/* ---------- Scan page: torch and the scan log (1.11.0) ---------- */
.scan-torch { position: absolute; right: 10px; bottom: 10px; z-index: 3; background: rgba(20, 22, 60, .86); color: #fff; border: 1px solid rgba(255, 255, 255, .35); }  /* 1.69.5: no blur over the live camera */
.scan-torch.on { background: var(--esn-orange); border-color: var(--esn-orange); color: var(--on-bright); }
.scan-log { margin: 14px 0 0; padding: 10px 12px; border: 1px solid var(--border); border-radius: var(--r-md); background: var(--card); }
.scan-log summary { cursor: pointer; display: flex; align-items: center; gap: 8px; }
.scan-log ul { list-style: none; margin: 8px 0 0; padding: 0; }
.scan-log li { display: flex; align-items: center; gap: 8px; padding: 6px 0; border-top: 1px solid var(--border); font-size: .9rem; }
.scan-log li > span { flex: 1; min-width: 0; }
.scan-log li time { color: var(--muted); font-size: .8rem; font-variant-numeric: tabular-nums; }
.scan-log li.ok .material-symbols-rounded { color: var(--esn-green); }
.scan-log li.bad .material-symbols-rounded { color: var(--esn-magenta); }

/* ---------- Scan page: who is still missing (1.11.0) ---------- */
.scan-missing-panel { margin: -6px 0 10px; padding: 10px 12px; border: 1px solid var(--border); border-radius: var(--r-md); background: var(--card); }
.scan-missing-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 6px; }
.scan-missing-head .btn { margin-left: auto; }
.scan-missing-list { list-style: none; margin: 0; padding: 0; max-height: 320px; overflow: auto; }
.scan-missing-list li { display: flex; align-items: center; gap: 8px; padding: 6px 0; border-top: 1px solid var(--border); }
.scan-missing-list li .btn { margin-left: auto; }

/* ---------- Event detail registrations (1.10.0) ---------- */
.reg-sort { align-self: flex-start; flex: 0 0 auto; width: auto; min-width: 170px; font: inherit; font-size: .85rem; padding: 8px 10px; border: 1px solid var(--border); border-radius: 10px; background: var(--card); color: var(--ink); }
.regs-table th.th-sort { cursor: pointer; user-select: none; white-space: nowrap; }
.regs-table th.th-sort:hover { color: var(--accent-text); }
.regs-table th.th-sort.on { color: var(--accent-text); }
.regs-table .th-arrow { font-size: .7em; opacity: .8; }
.regs-table tr.row-link { cursor: pointer; }
.regs-table tr.row-link:hover td { background: var(--hover); }
@media (max-width: 820px) {
  .regs-table thead { display: none; }
  .reg-sort { align-self: stretch; width: 100%; }
}

/* ---------- Cash registers (1.10.0) ---------- */
.reg-swatch { display: inline-block; width: 10px; height: 10px; border-radius: 3px; background: var(--c, #9a9cb5); margin-right: 7px; vertical-align: -1px; flex: none; }
.reg-list { list-style: none; margin: 0; padding: 0; }
.reg-list li { display: flex; align-items: center; gap: 4px; padding: 8px 0; border-bottom: 1px solid var(--border); }
.reg-list li:last-child { border-bottom: none; }
.reg-list li .card-actions { margin-left: auto; display: flex; gap: 6px; }
.reg-list.retired li { color: var(--muted); }
.cash-pick .reg-swatch { margin-right: 6px; }

/* ---------- Profile picture card (1.1.37) ---------- */
.pic-row { display: flex; align-items: center; gap: 16px; margin: 12px 0 10px; flex-wrap: wrap; }
.pic-actions { display: flex; flex-direction: column; align-items: flex-start; gap: 8px; min-width: 0; }
.pic-actions .btn { margin: 0; }
.av-row { display: flex; align-items: center; gap: 10px; }
.av-row > div { min-width: 0; }
.ud-title { display: flex; align-items: center; gap: 12px; }
.av-pair { display: inline-flex; align-items: center; gap: 6px; flex-wrap: wrap; }

/* ---------- Payments log (1.1.21) ---------- */
/* Payments log (1.1.21) */
/* Phone action rows: equal heights inside the two-column grid */
/* The event page action row on a phone: tighter buttons so the labels fit */
/* The links page payment tiles wrap their label instead of overflowing */
.pay-tiles .pay-tile { text-align: left; font: inherit; cursor: pointer; border: 1px solid var(--border); white-space: normal; }
.pay-tiles .pay-tile.active { outline: 2px solid var(--esn-dark); outline-offset: -2px; }
.pay-tiles .pay-tile.warn .num { color: var(--danger); }
.pay-tile .num small { font-size: .8rem; font-weight: 700; color: var(--muted); }
.pay-method { font-size: .8rem; white-space: nowrap; }
.pay-flag { color: var(--danger); font-weight: 700; font-size: .8rem; display: inline-flex; align-items: center; gap: 3px; }
.pay-ok { font-weight: 700; font-size: .8rem; display: inline-flex; align-items: center; gap: 3px; color: var(--green-text); }

/* ---------- Board space (1.1.20) ---------- */
.bd-avatar img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; border-radius: 50%; }  /* 1.1.37: Profile picture card */
/* Board space (1.1.20): next-meeting hero, meeting timeline, to-do progress, birthday strip */
.board-hero {
  display: flex; align-items: center; gap: 18px; padding: 18px 20px; border-radius: var(--r-lg); color: #fff;
  background: linear-gradient(120deg, var(--esn-dark) 0%, #3d43c9 55%, var(--esn-cyan) 130%);
  box-shadow: 0 10px 28px rgba(46, 49, 146, .22); text-decoration: none;
}
.board-hero:hover { text-decoration: none; filter: brightness(1.04); }
.board-hero.empty { background: var(--card); color: var(--ink); border: 1px dashed var(--border); box-shadow: none; }
.bh-date { flex: none; display: flex; flex-direction: column; align-items: center; justify-content: center; min-width: 88px; padding: 10px 12px; border-radius: var(--r-md); background: rgba(255,255,255,.14); text-align: center; line-height: 1.1; }
.board-hero.empty .bh-date { background: var(--bg); color: var(--muted); }
.bh-date b { font-size: 2.4rem; font-weight: 900; }
.bh-date span { font-size: .75rem; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; opacity: .9; }
.bh-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.bh-kicker { font-size: .75rem; font-weight: 800; text-transform: uppercase; letter-spacing: .08em; opacity: .85; display: inline-flex; align-items: center; gap: 4px; }
.bh-title { font-size: 1.3rem; font-weight: 900; line-height: 1.2; }
.bh-meta { font-size: .9rem; opacity: .92; display: inline-flex; align-items: center; gap: 4px; flex-wrap: wrap; }
.board-hero .mt-chips { margin-top: 4px; }
.board-hero .badge { background: rgba(255,255,255,.18); color: #fff; }
.board-hero .badge-paid { background: var(--esn-green); }
.bh-cta { flex: none; background: #fff; color: var(--esn-dark); font-weight: 800; border: 0; }
.board-hero.empty .bh-cta { background: var(--esn-green); color: var(--on-bright); }
.stat-warn { font-size: .75rem; font-weight: 800; color: var(--danger); vertical-align: middle; }
.mt-list { display: flex; flex-direction: column; gap: 8px; margin: 0 0 18px; }
.bd-grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: 0 22px; align-items: start; }  /* 1.78.8: the Board page: meetings, and beside them what needs doing */
.bd-side { display: flex; flex-direction: column; gap: 12px; margin-bottom: 18px; }
.bd-side > .news-strip, .bd-side > .form-card { margin: 0; }
@media (min-width: 900px) {
  .bd-grid { grid-template-columns: minmax(0, 1.7fr) minmax(0, 1fr); }
  .bd-side { position: sticky; top: 84px; }
}
.mt-item { display: flex; align-items: center; gap: 14px; background: var(--card); border: 1px solid var(--border); border-radius: var(--r-md); padding: 10px 12px; color: var(--ink); }
.mt-item:hover { text-decoration: none; border-color: var(--esn-cyan); }
.mt-item.past { opacity: .85; }
.mt-date { flex: none; display: flex; flex-direction: column; align-items: center; width: 52px; padding: 6px 0; border-radius: 10px; background: var(--esn-cyan); line-height: 1.05; color: var(--on-bright, #12142a); }
.mt-item.past .mt-date { background: var(--bg); border: 1px solid var(--border); color: var(--muted); }
.mt-date b { font-size: 1.3rem; font-weight: 900; }
.mt-date small { font-size: .75rem; font-weight: 800; text-transform: uppercase; letter-spacing: .05em; }
.mt-date .mt-dow { opacity: .8; }
.mt-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.mt-body strong { font-size: .95rem; }
.mt-chips { display: flex; flex-wrap: wrap; gap: 4px; }
.mt-chips .badge { display: inline-flex; align-items: center; gap: 3px; }
.mt-go { color: var(--muted); }
.todo-progress { margin: 0 0 10px; }
.tp-bar { height: 8px; border-radius: 6px; background: var(--border); overflow: hidden; }
.tp-bar i { display: block; height: 100%; background: linear-gradient(90deg, var(--esn-green), var(--esn-cyan)); border-radius: 6px; width: 100%; transform: translateX(calc(var(--p, 0%) - 100%)); transition: transform .4s ease; }
.tp-line { display: flex; justify-content: space-between; align-items: center; gap: 10px; flex-wrap: wrap; margin-top: 6px; font-size: .8rem; color: var(--muted); }
.tp-owners { display: flex; flex-wrap: wrap; gap: 6px; }
.bd-strip { display: flex; gap: 10px; overflow-x: auto; padding: 2px 0 6px; scrollbar-width: thin; }
.bd-card { flex: none; width: 92px; display: flex; flex-direction: column; align-items: center; gap: 3px; text-align: center; padding: 10px 6px; border-radius: var(--r-md); background: var(--bg); border: 1px solid var(--border); }
.bd-card.today { border-color: var(--esn-magenta); background: rgba(236, 0, 140, .06); }
.bd-card strong { font-size: .8rem; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bd-card small { font-size: .75rem; color: var(--muted); }
.bd-avatar { position: relative; overflow: hidden; flex: none; width: 40px; height: 40px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; font-weight: 900; font-size: .85rem; color: #fff; background: hsl(var(--h, 200) 55% 48%); }
.bd-card.today .bd-avatar { background: var(--esn-magenta); }
.tp-owners .chip { min-height: 30px; }  /* 1.32.0: board pages measured for the first time */
@media (max-width: 640px) {
  .board-hero { flex-wrap: wrap; gap: 12px; padding: 14px; }
  .bh-date { min-width: 72px; }
  .bh-date b { font-size: 1.7rem; }
  .bh-cta { width: 100%; justify-content: center; }
}

/* ---------- Profile & ESNcard ---------- */
.profile-grid { display: grid; grid-template-columns: 1.4fr 1fr; gap: 24px; margin-bottom: 44px; }
/* Replica of the official ESNcard layout */
.esncard {
  display: flex;
  border-radius: var(--r-lg);
  overflow: hidden;
  background: #fff;
  border: 1px solid var(--border);
  box-shadow: var(--shadow-lg);
  max-width: 440px;
  font-size: 10px;                  /* card scales off this */
}
.esncard-grey { filter: grayscale(.8) brightness(.96); }
.esncard-left {
  flex: 0 0 37%;
  background: linear-gradient(160deg, #2aa7e6 0%, #1d63c8 55%, var(--esn-dark) 100%);
  color: #fff;
  padding: 10% 6% 6% 7%;
  display: flex;
  flex-direction: column;
}
.esncard-brand { font-size: 1.5em; font-weight: 900; letter-spacing: .3px; }
.esncard-sub { font-size: .78em; line-height: 1.25; opacity: .85; margin-top: 1px; }
/* 1.26.0: the ESN Passport level on the blue side, where the plastic card
   prints its photo notice. Tap goes to the passport. */
.esncard-level {
  margin-top: auto; padding-top: 7%;
  display: flex; align-items: center; gap: 5px;
  color: #fff; text-decoration: none; min-width: 0;
}
.esncard-level:hover { text-decoration: none; }
.esncard-level i {
  flex: none; width: 2.1em; height: 2.1em; border-radius: 50%;
  background: var(--lvlc); color: #fff; font-style: normal; font-weight: 900; font-size: 1em;
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 0 0 2px rgba(255, 255, 255, .55);
}
.esncard-level > span { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.esncard-level b { font-size: .82em; font-weight: 800; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.esncard-level small { font-size: .66em; opacity: .85; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.esncard-level em { display: block; height: 3px; border-radius: 2px; background: rgba(255, 255, 255, .28); overflow: hidden; margin-top: 2px; }
.esncard-level u { display: block; height: 100%; background: var(--lvlc); border-radius: 2px; text-decoration: none; }
.esncard-barcode-btn { flex: 1; min-width: 0; display: flex; align-items: flex-end; background: none; border: 0; padding: 0; margin: 0; cursor: pointer; border-radius: 4px; }
.card-show { width: min(420px, 100%); text-align: center; }
/* a phone dialog card is full width */
.card-show-codes { display: flex; flex-direction: column; align-items: center; gap: 14px; background: #fff; border-radius: var(--r-md); padding: 14px; }
.card-show-bar { width: 100%; max-width: 380px; height: auto; display: block; }
.card-show-qr img, .card-show-qr canvas { display: block; }
.card-show-no { margin: 12px 0 4px; font-family: ui-monospace, "SF Mono", Menlo, monospace; font-weight: 800; font-size: 1.3rem; letter-spacing: 2px; }
.esncard-photo {
  margin-top: 10%;
  aspect-ratio: 3 / 4;
  border-radius: var(--r-sm);
  background: rgba(255, 255, 255, .18);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  min-height: 0;
}
.esncard-photo img { width: 100%; height: 100%; object-fit: cover; }
.esncard-photo span { font-weight: 900; letter-spacing: 2px; font-size: 1.2em; opacity: .8; }
.esncard-notvalid {
  font-size: .72em;
  text-align: center;
  margin-top: auto;
  padding-top: 6%;
  opacity: .85;
  line-height: 1.3;
  text-transform: uppercase;
  letter-spacing: .5px;
}
.esncard-right {
  position: relative;               /* 1.75.0: the skyline behind the fields */
  flex: 1;
  padding: 6% 6% 5% 6%;
  display: flex;
  flex-direction: column;
  /* The card replica is always a LIGHT physical card — its text must stay
     dark in dark mode too (was var(--ink) → unreadable white-on-white). */
  color: #191a2e;
  min-width: 0;
}
.esncard-value { color: #14264a; background: #bfe3f8; border-radius: 5px; padding: 3px 8px; font-size: 1.05em; font-weight: 700; min-height: 1.7em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.esncard-value.is-expired { color: #b42318; text-decoration: line-through; } /* 1.70.1: an expired card keeps its date, struck through */
.esncard-logo {
  align-self: flex-end;
  display: flex;
  align-items: center;
  gap: 3px;
  margin: -2% 0 2%;
}
/* 1.26.0: the official ESN logo file, never redrawn. */
.esncard-logo img { width: 6.6em; height: auto; display: block; }
.esncard-field { margin-bottom: 3.5%; min-width: 0; }
.esncard-frow { display: flex; gap: 4%; }
.esncard-frow .esncard-field { flex: 1; }
/* Dates like 15.08.2026 must never truncate — let that box breathe */
.esncard-frow .esncard-field + .esncard-field { flex: 0 0 auto; min-width: 34%; }
.esncard-label { font-size: .95em; font-weight: 700; color: #45536b; margin-bottom: 2px; }
.esncard-value.mono { font-family: ui-monospace, "SF Mono", Menlo, monospace; letter-spacing: 1px; }
.esncard-bottom { display: flex; align-items: flex-end; gap: 6%; }
.esncard-bottom .esncard-field { flex: 1; margin-bottom: 0; }
.esncard-barcode {
  flex: 1;
  min-width: 0;
  width: 100%;
  height: 3.2em;
}
.esncard-barcode-empty { flex: 1; }
.esncard-status { font-size: .8rem; color: var(--muted); margin-top: 10px; }
/* 1.58.1: the printed card - the official blank ESNcard with the details in its own boxes (measured on 2000 x 1264) */
.esncard-printed { display: block; position: relative; aspect-ratio: 2000 / 1264; container-type: inline-size; background: transparent; border: 0; box-shadow: none; filter: drop-shadow(0 6px 16px rgba(25, 26, 46, .16)); }
.esncard-printed.esncard-grey { filter: grayscale(.8) brightness(.96) drop-shadow(0 6px 16px rgba(25, 26, 46, .16)); }
.ecp-tpl { position: absolute; inset: 0; width: 100%; height: 100%; display: block; z-index: 1; pointer-events: none; }
.ecp-photo { position: absolute; left: 4.3%; top: 29.4%; width: 30.4%; height: 63.6%; background: #fff; z-index: 0; overflow: hidden; }
.ecp-photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
.ecp-f { position: absolute; z-index: 2; left: 40.95%; height: 8.47%; padding: 0 1.4cqw; color: #1c1d3a; font-weight: 700; font-size: 2.9cqw; line-height: 5.35cqw; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ecp-name { top: 29.91%; width: 53.35%; font-size: 3.2cqw; }
.ecp-nat { top: 42.33%; width: 34%; }
.ecp-uni { top: 54.83%; width: 53.2%; }
.ecp-sec { top: 67.17%; width: 34%; }
.ecp-no { top: 81.49%; width: 53.2%; display: flex; align-items: center; justify-content: space-between; gap: 2cqw; }
.ecp-no .mono { font-family: ui-monospace, "SF Mono", Menlo, monospace; font-size: 2.8cqw; letter-spacing: .1em; flex: none; }
.ecp-no .esncard-barcode-btn { flex: 0 1 46%; height: 78%; align-items: center; justify-content: flex-end; }
.ecp-no .esncard-barcode { flex: none; height: 100%; width: 100%; }
.ecp-nocard { display: inline-flex; align-items: center; gap: 1cqw; font-size: 2.5cqw; font-weight: 700; color: #45536b; }
.ecp-nocard a { color: var(--esn-magenta); }
.ecp-nocard .material-symbols-rounded { font-size: 3.4cqw; }
.ecp-digits { position: absolute; z-index: 2; left: 0; width: 100%; height: 8.47%; pointer-events: none; }
.ecp-dob { top: 42.33%; }
.ecp-since { top: 67.17%; }
.ecp-digits i { position: absolute; top: 0; width: 2.55%; height: 100%; display: grid; place-items: center; background: #d6e6f6; color: #1c1d3a; font-style: normal; font-weight: 700; font-size: 3.1cqw; }
.ecp-digits i:nth-of-type(1) { left: 76.5%; }
.ecp-digits i:nth-of-type(2) { left: 79.25%; }
.ecp-digits i:nth-of-type(3) { left: 82.7%; }
.ecp-digits i:nth-of-type(4) { left: 85.45%; }
.ecp-digits i:nth-of-type(5) { left: 88.9%; }
.ecp-digits i:nth-of-type(6) { left: 91.65%; }
/* v0.86: interactive card — subtle 3D tilt following the pointer, with a
   glossy sheen that sweeps across. Pure CSS variables driven from JS;
   disabled automatically on touch devices (no hover). */
.esncard-stage { perspective: 900px; display: block; }
.esncard-tilt {
  transform: rotateX(var(--tiltX, 0deg)) rotateY(var(--tiltY, 0deg));
  transition: transform var(--t-base) ease-out;
  will-change: transform;
  position: relative;
  animation: cardIntro .5s ease-out;
}
.esncard-tilt::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: var(--r-lg);
  pointer-events: none;
  z-index: 3;
  background: radial-gradient(circle at var(--mx, 50%) var(--my, 50%),
    rgba(255, 255, 255, .35) 0%, rgba(255, 255, 255, 0) 45%);
  opacity: var(--sheen, 0);
  transition: opacity .25s;
  mix-blend-mode: soft-light;
}
/* 1.9.0: the foil. A band of ESN colours that slides across as the card is
   tilted, which is what makes it read as a physical card rather than a
   rectangle with a photo on it. Soft-light keeps it a sheen on top of the
   artwork instead of a coloured film over it. Driven from --foil in app.js:
   pointer angle on a laptop, the phone's own angle on a phone. */
.esncard-tilt::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: var(--r-lg);
  pointer-events: none;
  z-index: 2;
  background: linear-gradient(112deg,
    rgba(255, 255, 255, 0) 34%,
    rgba(0, 174, 239, .55) 41%,
    rgba(120, 90, 220, .45) 46%,
    rgba(236, 0, 140, .50) 50%,
    rgba(244, 123, 32, .46) 55%,
    rgba(122, 193, 67, .40) 60%,
    rgba(255, 255, 255, 0) 67%);
  background-size: 250% 100%;
  background-position: var(--foil, 50%) 0;
  /* Normal blending, not soft-light. Most of this card is white, and
     soft-light over white is white: the whole band disappeared on exactly the
     half you look at. Real foil shows as colour on a pale card because it
     reflects some wavelengths and not others, so plain alpha is also the
     honest one. */
  /* --sheen carries how far the card is actually leaning, so a card held flat
     is almost clean and only a tilted one catches the light. That keeps the
     name, the date of birth and the card number readable, which is the whole
     point of the card. */
  opacity: calc(var(--sheen, 0) * .42);
  transition: opacity var(--t-slow);
}
@media (max-width: 820px) {
  .card-show { width: 100%; }
  .esncard-stage { order: 0; }
  .profile-grid { grid-template-columns: minmax(0, 1fr); }  /* Responsive */
}
@media (prefers-reduced-motion: reduce) {
  .esncard-tilt { animation: none; transform: none; }
  .esncard-tilt::before, .esncard-tilt::after { opacity: 0; }
}

/* ---------- Account menu (v0.86) ---------- */
/* "Already have a card?" uses the app's chevron, not the browser triangle */
.acct-details > summary { list-style: none; display: flex; align-items: center; gap: 6px; cursor: pointer; font-size: .9rem; font-weight: 700; }
.acct-details > summary::-webkit-details-marker { display: none; }
.acct-details > summary::after { content: "expand_more"; font-family: "Material Symbols Rounded"; margin-left: auto; opacity: .6; }
.acct-details[open] > summary::after { content: "expand_less"; }
/* "No card yet" tag on the greyed replica (outside the grayscale filter) */
.esncard-preview-tag {
  position: absolute; bottom: 10px; right: 10px; z-index: 2;
  display: inline-flex; align-items: center; gap: 4px;
  background: var(--esn-orange); color: var(--on-bright); padding: 4px 10px; border-radius: 999px;
  font-size: .7rem; font-weight: 800; letter-spacing: .05em; text-transform: uppercase;
  box-shadow: 0 2px 8px rgba(0, 0, 0, .18);
}
.esncard-preview-tag .material-symbols-rounded { font-size: 14px; }
.acct-title { max-width: var(--w-wide); margin-left: auto; margin-right: auto; }
/* the app bar already says Account */
.account-foot-links {
  text-align: center;
  font-size: .8rem;
  color: var(--muted);
}
.account-foot-links a { color: var(--muted); text-decoration: underline; }
@media (max-width: 820px) {
  .acct-title { display: none; }
  .account-foot-links { order: 4; }
}

/* ---------- Account screen (avatar tap) ---------- */
.account-menu .menu-role { margin-left: 6px; font-size: .75rem; vertical-align: middle; text-transform: none; letter-spacing: 0; }
/* v0.86: grouped account menu with icons */
.account-menu .menu-group {
  font-size: .75rem;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: .8px;
  color: var(--muted);
  padding: 12px 16px 4px;
  background: var(--surface2);
}  /* v0.86: Account menu */
.account-menu a .material-symbols-rounded,
.account-menu button .material-symbols-rounded,
.account-menu .menu-static .material-symbols-rounded {
  font-size: 20px;
  vertical-align: -4.5px;
  margin-right: 10px;
  color: var(--esn-cyan);
  opacity: .9;
}
.account-menu #btn-signout-account .material-symbols-rounded { color: var(--muted); }
/* Perk rows the user can't open yet (1.1.11) */
.account-menu a.locked { color: var(--muted); }
.account-menu a.locked .material-symbols-rounded { color: var(--muted); opacity: .7; }
.account-menu .menu-lock-i .material-symbols-rounded { font-size: 16px; margin: 0; color: var(--muted); vertical-align: -3px; }
/* Appearance: three-way switch inside a menu row */
.account-menu .menu-row {
  display: flex; align-items: center; flex-wrap: wrap; row-gap: 6px; padding: 10px 16px; border-bottom: 1px solid var(--border);
  font-size: .9rem; font-weight: 700; color: var(--ink); min-height: 50px;
}
.account-menu .menu-row .material-symbols-rounded { font-size: 20px; vertical-align: -4.5px; margin-right: 10px; color: var(--esn-cyan); opacity: .9; }
.account-menu .seg { margin-left: auto; display: inline-flex; border: 1px solid var(--border); border-radius: 999px; overflow: hidden; background: var(--surface2); }
.account-menu .seg button {
  border: 0; border-bottom: 0; background: none;
  font-family: inherit; font-size: .8rem; font-weight: 700; color: var(--muted); cursor: pointer; white-space: nowrap; min-height: 32px; padding: 6px 12px;
}
.account-menu .seg button.active { background: var(--esn-dark); color: #fff; }
.account-menu .seg button:hover { background: var(--hover); }
.account-menu .seg button.active:hover { background: var(--esn-dark); }
.account-wrap {
  max-width: 460px;
  margin: 26px auto 44px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.account-wrap .esncard { max-width: none; }
.account-wrap .esncard-status { margin-top: -4px; }
.account-menu {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
.account-menu a, .account-menu button, .account-menu .menu-static {
  display: flex;
  align-items: center;
  padding: 13px 16px;
  border: none;
  border-bottom: 1px solid var(--border);
  background: none;
  font-family: inherit;
  font-size: .9rem;
  font-weight: 700;
  color: var(--ink);
  cursor: pointer;
  text-align: left;
}
.account-menu a:hover, .account-menu button:hover { background: var(--hover); text-decoration: none; }
.account-menu > :last-child { border-bottom: none; }
.account-menu #btn-signout-account { color: var(--muted); }
.account-menu .chev { color: var(--muted); font-size: 1.15rem; margin-left: auto; transition: transform .15s ease; }
.account-menu .menu-value {
  margin-left: auto;
  font-weight: 600;
  font-size: .85rem;
  color: var(--accent-text);
}
.account-menu .menu-value + .chev { margin-left: 8px; }
/* 1.9.0: the release notes are team-only, so a student sees the version as a
   fact rather than as a door. Same row, no hover, no chevron. */
.account-menu .menu-static { color: var(--muted); font-weight: 700; cursor: default; }
.account-menu .menu-static .material-symbols-rounded { color: var(--muted); opacity: .8; }
/* Mobile: natural app order — card, shortcuts, status card, menu, foot links.
   display:contents lifts the two columns' children into the single flex
   column so they can interleave. */
.account-menu a:active, .account-menu button:active { background: var(--hover); }
.menu-value {
  font-variant-numeric: tabular-nums;
}  /* v0.109.1: Design pass — playbook fundamentals */
.account-menu a, .account-menu button { min-height: 50px; }
@media (min-width: 821px) {
  .account-wrap {
    max-width: var(--w-wide);
    display: grid;
    grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr);
    gap: 0 32px;
    align-items: start;
  }
  .account-menu a.m-only-row { display: none; }
  /* My tickets is in the top nav; version is in the footer */
  .account-wrap .esncard { font-size: 11.5px; }
  /* card scales up a notch */
}
@media (max-width: 820px) {
  .account-menu { order: 3; }
}
@media (hover: hover) {
  .account-menu a:hover .chev { transform: translateX(2px); }  /* v0.109.1: Design pass — playbook fundamentals */
}
@media (pointer: coarse) {
  .account-menu a, .account-menu button { min-height: 48px; }  /* v1.5.0: audit */
}

@media (max-width: 820px) {
  /* status right under its card */
  .quick-grid { order: 2; }
}

/* ---------- Settings groups ---------- */
/* Settings page: group headers between the cards */
.settings-group {
  font-size: .8rem;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: .8px;
  color: var(--muted);
  margin: 26px 0 10px;
  display: flex;
  align-items: center;
  gap: 8px;
}
.settings-group:first-of-type { margin-top: 10px; }
.settings-group .material-symbols-rounded { color: var(--esn-cyan); }
.settings-group::after { content: ""; flex: 1; height: 1px; background: var(--border); }

/* ---------- Ticket options fold ---------- */
.ticket-more-body { margin-top: 10px; display: flex; flex-direction: column; gap: 8px; align-items: stretch; }

/* ---------- Sign-in ---------- */
/* Google sign-in buttons — per Google's branding the G sits on a white
   button with dark text, in light AND dark mode. */
.btn-google {
  background: #fff;
  color: #1f1f1f;
  border: 1px solid #dadce0;
  align-items: center;
  justify-content: center;
  gap: 10px;
}
.btn-google:hover { background: #f7f8f8; }
/* Returning user (flag set before first paint): no Sign-in button flash
   while Firebase restores the session. app.js flips data-auth on change. */
html[data-auth="1"] #btn-signin { display: none; }
.btn-google .g-logo { width: 18px; height: 18px; flex: 0 0 18px; }
[data-theme="dark"] .btn-google { background: #fff; color: #1f1f1f; border-color: #dadce0; }
.signin-state .form-hint { max-width: 340px; margin: 6px auto 16px; }
.signin-state p strong { font-size: 1rem; }

/* ---------- Ticket / QR ---------- */
.checkin-status .material-symbols-rounded { font-size: 56px; }
.ticket-panel {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
  max-width: 440px;
  margin: 36px auto;
  overflow: hidden;
  text-align: center;
}
.ticket-head {
  background: var(--esn-dark);
  border-bottom: 4px solid var(--esn-cyan);
  color: #fff;
  padding: 22px;
}
.ticket-head h1 { font-size: 1.3rem; font-weight: 900; }
.ticket-head p { font-size: .85rem; color: #d9dbf2; margin-top: 4px; }
.ticket-body { padding: 26px 22px 30px; display: flex; flex-direction: column; align-items: center; gap: 12px; }
.qr-box {
  background: #fff;
  padding: 14px;
  border: 1px solid var(--border);
  border-radius: 10px;
  display: inline-block;
}
.qr-box img, .qr-box canvas, .qr-box table { display: block; }
.ticket-code { font-family: ui-monospace, "SF Mono", Menlo, monospace; font-size: .75rem; color: var(--muted); word-break: break-all; font-variant-numeric: tabular-nums; }
.ticket-divider { width: 100%; border: none; border-top: 2px dashed var(--border); margin: 6px 0; }
.checkin-panel {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
  max-width: 520px;
  margin: 36px auto;
  padding: 30px;
  text-align: center;
}
.checkin-status { font-size: 2.8rem; margin-bottom: 6px; }
.checkin-panel h1 { font-size: 1.45rem; }
.checkin-details {
  text-align: left;
  margin: 18px 0;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  padding: 14px 18px;
  font-size: .9rem;
}
.checkin-details p { margin: 4px 0; }
.ticket-panel.is-in .qr-box { opacity: .55; }  /* v0.137: Ticket page polish */
.checkin-panel p .btn + .btn { margin-left: 8px; }  /* 1.14.1: one button */

/* ---------- QR scanner ---------- */
.scan-panel { max-width: 520px; margin: 0 auto 44px; }
.scan-video-wrap {
  position: relative;
  border-radius: var(--radius);
  overflow: hidden;
  background: #000;
  box-shadow: var(--shadow-lg);
}
.scan-video-wrap video { width: 100%; display: block; }
.scan-frame {
  position: absolute;
  inset: 14%;
  border: 3px solid rgba(255, 255, 255, .9);
  border-radius: var(--r-lg);
  pointer-events: none;
  box-shadow: 0 0 0 999px rgba(0, 0, 0, .28);
}
/* ---- 1.58.0: the door - one screen, the camera fills it, nothing to scroll ---- */
.door { max-width: var(--w-read); margin: 0 auto; padding: 10px 0 12px; display: flex; flex-direction: column; gap: 10px; height: calc(100dvh - var(--hdr, 64px) - 24px); min-height: 440px; position: relative; }
.door-ev { width: 100%; display: flex; align-items: center; gap: 12px; padding: 10px 14px; border: 0; border-radius: var(--r-lg); background: var(--esn-dark); color: #fff; font: inherit; text-align: left; cursor: pointer; box-shadow: var(--shadow-lg); }
.door-ev.warn { background: var(--esn-magenta); }
.door-ev-ic { flex: none; width: 38px; height: 38px; border-radius: 50%; display: grid; place-items: center; background: rgba(255, 255, 255, .14); }
.door-ev-txt { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.door-ev-txt strong { font-size: 1rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.door-ev-txt small { font-size: .8rem; opacity: .85; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.door-ev-txt small b { font-size: .9rem; }
.door-queue { margin: 0; }
.door-cam { position: relative; flex: 1 1 auto; min-height: 0; border-radius: var(--r-lg); overflow: hidden; background: #0d0e26; isolation: isolate; }
.door-cam video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }
.door-guide { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); width: min(80%, 440px); aspect-ratio: 1.6; border-radius: var(--r-lg); box-shadow: 0 0 0 999px rgba(0, 0, 0, .28); pointer-events: none; z-index: 1; }
.door-guide.qr { width: min(64%, 300px); aspect-ratio: 1; }
.door-guide i { position: absolute; width: 30px; height: 30px; border: 4px solid #fff; border-radius: 6px; }
.door-guide i:nth-child(1) { left: -2px; top: -2px; border-right: 0; border-bottom: 0; }
.door-guide i:nth-child(2) { right: -2px; top: -2px; border-left: 0; border-bottom: 0; }
.door-guide i:nth-child(3) { left: -2px; bottom: -2px; border-right: 0; border-top: 0; }
.door-guide i:nth-child(4) { right: -2px; bottom: -2px; border-left: 0; border-top: 0; }
.door-cam:has(.door-sheet:not(.hidden)) .door-guide, .door-cam:has(.door-sheet:not(.hidden)) .door-hint { opacity: 0; }
.door-hint { position: absolute; top: 12px; left: 50%; transform: translateX(-50%); z-index: 2; margin: 0; max-width: calc(100% - 24px); padding: 6px 14px; border-radius: 999px; background: rgba(18, 20, 56, .88); color: #fff; font-size: .85rem; font-weight: 700; text-align: center; }  /* 1.69.5: no blur over the live camera */
.door-cam-tools { position: absolute; right: 10px; bottom: 10px; z-index: 3; display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 8px; max-width: calc(100% - 20px); }
.door-cam-tools .scan-torch { position: static; }
.kiosk-cam-tools { position: absolute; left: 10px; bottom: 10px; z-index: 3; display: flex; gap: 8px; }
.kiosk-cam-tools .scan-torch { position: static; }
.scan-cam { display: inline-flex; align-items: center; gap: 4px; cursor: pointer; }  /* 1.59.0: which camera scans */
.scan-cam select { appearance: none; -webkit-appearance: none; background: transparent; border: 0; color: inherit; font: inherit; font-size: .8rem; font-weight: 700; max-width: 9.5em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; padding: 0 2px; cursor: pointer; }
.scan-cam select:focus-visible { outline: 2px solid var(--esn-cyan); outline-offset: 2px; }
.scan-cam option { color: #1c1d3a; background: #fff; }
.door-start { position: absolute; inset: 0; z-index: 4; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 12px; padding: 24px; text-align: center; color: #fff; background: radial-gradient(circle at 50% 40%, #2e3192 0%, #0d0e26 75%); }
.door-start > .material-symbols-rounded { font-size: 56px; opacity: .55; }
.door-start small { max-width: 34ch; opacity: .8; font-size: .85rem; line-height: 1.45; }
.door-sheet { position: absolute; left: 8px; right: 8px; bottom: 8px; z-index: 5; max-height: calc(100% - 16px); overflow: auto; overscroll-behavior: contain; padding: 14px 16px 16px; border-radius: var(--r-lg); border-top: 6px solid var(--border); background: var(--card); color: var(--ink); text-align: center; box-shadow: 0 -6px 30px rgba(0, 0, 0, .35); animation: sheet-in .18s ease-out; }
.door-sheet.good { border-top-color: var(--esn-green); }
.door-sheet.bad { border-top-color: var(--esn-magenta); }
.door-sheet .checkin-status { font-size: 2rem; margin-bottom: 2px; }
.door-sheet .checkin-status .material-symbols-rounded { font-size: 44px; }
.door-sheet h1 { font-size: 1.15rem; margin: 0 0 6px; }
.door-sheet .door-verdict.big { padding: 10px 12px; margin: 8px 0; }
.door-sheet .door-verdict.big .material-symbols-rounded { font-size: 28px; }
.door-sheet .door-verdict.big span { font-size: 1.15rem; }
.door-sheet .checkin-details { text-align: left; margin: 8px 0 0; }
.door-sheet .checkin-details p { margin: 3px 0; font-size: .9rem; }
.door-reading { margin: 6px 0; display: flex; align-items: center; justify-content: center; gap: 8px; font-weight: 700; color: var(--muted); }
.scan-result-actions { display: flex; flex-wrap: wrap; gap: 8px; justify-content: center; margin-top: 12px; }
.door-tools { display: grid; grid-template-columns: repeat(auto-fit, minmax(64px, 1fr)); gap: 8px; }
.door-tool { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px; min-height: 54px; padding: 6px 4px; border: 1px solid var(--border); border-radius: var(--r-md); background: var(--card); color: var(--ink); font: inherit; font-size: .75rem; font-weight: 700; cursor: pointer; text-decoration: none; }
.door-tool:hover { text-decoration: none; background: var(--hover); }
.door-tool .material-symbols-rounded { font-size: 22px; color: var(--esn-cyan); }
.door-panel { position: absolute; inset: 0; z-index: 9; display: flex; flex-direction: column; min-height: 0; background: var(--bg); border-radius: var(--r-lg); box-shadow: var(--shadow-lg); animation: sheet-in .18s ease-out; }
.door-panel-head { display: flex; align-items: center; gap: 10px; justify-content: space-between; padding: 12px 14px; border-bottom: 1px solid var(--border); }
.door-panel-head strong { font-size: 1.05rem; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.door-panel-body { flex: 1; min-height: 0; overflow: auto; overscroll-behavior: contain; padding: 12px 14px 16px; }
.door-panel-body .scan-target { position: static; }
.door-panel-body .scan-now { margin: 0; }
.door-panel-body .scan-log { margin: 0; }
.door-panel-body .scan-missing-list { max-height: none; }
@media (max-width: 820px) {
  .door { padding: 8px 0 10px; height: calc(100dvh - var(--hdr, 56px) - 84px - env(safe-area-inset-bottom) - 8px); min-height: 400px; gap: 8px; }
}
/* the scan target: one chip per type, the picked one filled */
.scan-types { display: flex; flex-wrap: wrap; gap: 6px; width: 100%; margin-top: 4px; }  /* 1.19.0: ticket types with a colour */
.scan-types .chip { border-color: rgba(255, 255, 255, .35); color: #fff; background: rgba(255, 255, 255, .08); }
.scan-types .chip.active { background: #fff; color: var(--esn-dark); border-color: #fff; }
.scan-types .chip .type-dot { box-shadow: 0 0 0 2px rgba(255, 255, 255, .5); }
.scan-types .chip.active .type-dot { box-shadow: none; }

/* ---- 1.16.0: the scanner keeps the camera on ---- */
/* A thin divider between the status chips and the ticket-type chips (1.16.0). */
.chip-sep { display: inline-block; width: 1px; height: 26px; background: var(--border); margin: 0 2px; align-self: center; }

/* ---------- Card scan sheet (1.1.44) ---------- */
.scan-sheet-title {
  margin: 0 0 14px;
  font-size: 1rem;
  display: flex;
  align-items: center;
  gap: 8px;
}
.scan-sheet-video {
  position: relative;
  border-radius: var(--r-md);
  overflow: hidden;
  background: #000;
  aspect-ratio: 4 / 3;
}
.scan-sheet-video video { width: 100%; height: 100%; object-fit: cover; display: block; }
/* A wide, short window: a card barcode is a letterbox, and framing it that
   way is what stops people filling the whole frame, which reads worst. */
.scan-sheet-frame {
  position: absolute;
  inset: 30% 8%;
  border: 3px solid rgba(255, 255, 255, .9);
  border-radius: var(--r-md);
  pointer-events: none;
  box-shadow: 0 0 0 999px rgba(0, 0, 0, .3);
}
.scan-sheet #cs-status { margin: 12px 0 0; min-height: 2.6em; }
.scan-sheet .dialog-actions { justify-content: space-between; }
.scan-sheet #cs-torch.active { background: var(--esn-cyan); color: var(--on-bright); }

/* ---------- Card lookup + door result (1.1.44) ---------- */
.scan-ev .scan-missing { flex: none; }  /* 1.11.0: Scan page */
.card-find { max-width: 560px; margin: 0 auto 44px; }
.card-find-row { display: flex; gap: 10px; flex-wrap: wrap; align-items: flex-end; }
.card-find-row .form-field { flex: 1 1 200px; margin: 0; }
.card-hit {
  display: flex;
  gap: 14px;
  align-items: center;
  flex-wrap: wrap;
  padding: 16px;
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background: var(--surface2);
  margin-top: 16px;
}
.card-hit .card-hit-who { flex: 1 1 200px; min-width: 0; }
.card-hit .card-hit-code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: .9rem;
}
.scan-ev.picked {
  outline: 2px solid var(--esn-cyan);
  outline-offset: 1px;
}
.scan-ev { cursor: pointer; display: flex; align-items: center; gap: 12px; flex-wrap: wrap; background: var(--card); border: 1px solid var(--border); border-radius: var(--r-md); padding: 12px 14px; margin-bottom: 8px; }
.scan-target {
  position: sticky;
  top: 0;
  z-index: 8;
  display: flex;
  gap: 10px;
  align-items: center;
  flex-wrap: wrap;
  padding: 10px 14px;
  margin: 0 0 16px;
  border-radius: var(--r-md);
  background: var(--esn-dark);
  color: #fff;
  box-shadow: var(--shadow-lg);
}
/* No event picked: the kiosk will admit anything, so say so loudly. */
.scan-target-warn { background: var(--esn-magenta); }
.scan-target strong { font-size: .95rem; }
.scan-target small { opacity: .82; }
.scan-target .btn { margin-left: auto; }
/* Fields were 40-43px; a finger wants 44 (buttons got this in 1.1.35). */
/* The check-in and pickup screens print one person on a label line. */
.ci-who { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }  /* 1.1.36: Form polish from the ticketing/ESNcard audit */
.ci-siblings { text-align: left; margin: 10px 0 0; padding: 10px 12px; border: 1px dashed var(--border); border-radius: var(--r-md); }  /* 1.16.0: the scanner keeps the camera on */
.ci-siblings ul { list-style: none; margin: 4px 0 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.ci-siblings li { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
/* the door: a band under the headline in the ticket's colour */
.ci-type { display: flex; align-items: center; justify-content: center; gap: 10px; margin: 6px auto 12px; padding: 10px 16px; border-radius: var(--r-md); max-width: 420px; background: var(--c); color: #fff; font-weight: 900; font-size: 1.15rem; letter-spacing: .5px; text-transform: uppercase; }  /* 1.19.0: ticket types with a colour */
.ci-type.mismatch { outline: 3px solid var(--esn-orange); outline-offset: 2px; }

/* ---------- Mobile home: greeting + swipe rail ---------- */
.m-greet { padding: 20px 0 2px; }
/* 1.48.0: on a wide screen the greeting and the passport share one row, the
   passport card a fixed width on the right; the phone keeps its column. */
@media (min-width: 900px) {
  .home-head { display: grid; grid-template-columns: minmax(0, 1fr) minmax(340px, 460px); column-gap: 28px; align-items: center; }
  .home-head > * { grid-column: 1 / -1; }
  .home-head > .m-greet { grid-column: 1; grid-row: 1; }
  .home-head > .pp-strip { grid-column: 2; grid-row: 1; margin: 18px 0 8px; }
}
.m-greet h1 { font-size: 1.45rem; font-weight: 900; }
.m-greet p { color: var(--muted); font-size: .85rem; }
/* 1.52.0: the week at a glance under the greeting */
.wk-strip { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 6px; margin: 12px 0 4px; max-width: 520px; }
.wk-day { display: flex; flex-direction: column; align-items: center; gap: 1px; padding: 7px 0 6px; border-radius: var(--r-md); border: 1px solid var(--border); background: var(--card); color: var(--muted); font: inherit; min-width: 0; }
.wk-day small { font-size: .75rem; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }
.wk-day b { font-size: 1.05rem; font-weight: 900; color: var(--ink); line-height: 1.2; }
.wk-day i { display: flex; gap: 3px; height: 7px; align-items: center; }
.wk-day em { width: 7px; height: 7px; border-radius: 50%; background: var(--c, var(--esn-cyan)); }
.wk-day.has { cursor: pointer; border-color: color-mix(in srgb, var(--esn-cyan) 40%, var(--border)); }
.wk-day.has:hover { background: var(--hover); }
.wk-day:not(.has) { border-style: dashed; }  /* 1.78.4: was opacity .55, which took the weekday under 3:1 */
.wk-day:not(.has) b { color: var(--muted); }
.wk-day.today { background: var(--esn-dark); border-color: var(--esn-dark); color: rgba(255,255,255,.75); opacity: 1; }
.wk-day.today b { color: #fff; }
.wk-day.today small { letter-spacing: 0; }  /* 1.78.7: TODAY fits a narrow day */
.wk-day.today em { box-shadow: 0 0 0 1.5px var(--esn-dark), 0 0 0 2.5px rgba(255,255,255,.7); }
html[data-theme="dark"] .wk-day.today { background: var(--esn-cyan); border-color: var(--esn-cyan); color: rgba(18,20,42,.75); }
html[data-theme="dark"] .wk-day.today b { color: #12142a; }
.event-card.flash { animation: card-flash 1.2s ease; }
@keyframes card-flash { 0%, 100% { box-shadow: var(--shadow); } 30% { box-shadow: 0 0 0 3px var(--esn-cyan), var(--shadow-lg); } }
.hscroll {
  display: flex;
  gap: 12px;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
  padding: 2px 24px 14px;
  margin: 0 -24px;
  scroll-padding-inline: 24px; /* 1.58.0: the first card snaps to the padding, not the screen edge */
  scrollbar-width: none;
}
.hscroll::-webkit-scrollbar { display: none; }
.mini-card {
  flex: 0 0 200px;
  scroll-snap-align: start;
  background: var(--card);
  border: 1px solid var(--border);
  border-left: 4px solid var(--accent, var(--esn-cyan));
  border-radius: var(--r-md);
  padding: 12px 14px;
  display: flex;
  flex-direction: column;
  gap: 5px;
  color: var(--ink);
  box-shadow: var(--shadow);
  touch-action: manipulation;
  -webkit-user-select: none;
  user-select: none;
}
.mini-card:hover { text-decoration: none; }
.mini-date { font-size: .75rem; font-weight: 700; color: var(--muted); text-transform: uppercase; letter-spacing: .5px; }
.mini-title {
  font-weight: 800;
  font-size: .9rem;
  line-height: 1.3;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  min-height: 2.4em;
}
.mini-price { font-size: .85rem; font-weight: 900; color: var(--accent-text); }
.mini-price.free { color: var(--esn-green); }
@media (max-width: 820px) {
  /* Tap feedback feels native */
  .mini-card:active { transform: scale(.97); }  /* Responsive */
  .hscroll { scrollbar-width: none; }  /* v0.109.1: Design pass — playbook fundamentals */
  .hscroll::-webkit-scrollbar { display: none; }
}

/* ============================================================
   Shift grid — spreadsheet-style layout like the party shiftlist
   ============================================================ */
.shift-grid-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; border: 1px solid var(--border); border-radius: 10px; }
.shift-grid { width: 100%; border-collapse: collapse; font-size: .8rem; }
.shift-grid th {
  background: var(--surface2); color: var(--muted);
  font-size: .75rem; text-transform: uppercase; letter-spacing: .6px;
  padding: 7px 10px; text-align: left; white-space: nowrap;
  border-bottom: 1px solid var(--border);
}
.shift-grid th.col-board { color: var(--accent-text); }
html[data-theme="dark"] .shift-grid th.col-board { color: #8b90ff; }
.shift-grid td {
  padding: 6px 8px; border-bottom: 1px solid var(--border);
  border-right: 1px solid var(--surface2); vertical-align: middle; min-width: 86px;
}
.shift-grid td:last-child { border-right: none; }
.shift-grid tbody tr:last-child td { border-bottom: none; }
.shift-grid td.col-task { min-width: 120px; max-width: 260px; overflow-wrap: anywhere; }
.shift-grid td.col-time { min-width: 70px; font-weight: 700; font-size: .75rem; color: var(--muted); white-space: nowrap; }
/* first column sticks while scrolling sideways on phones */
.shift-grid th:first-child, .shift-grid td:first-child {
  position: sticky; left: 0; background: var(--card); z-index: 1;
  box-shadow: 1px 0 0 var(--border);
}
.shift-grid th:first-child { background: var(--surface2); }
.cell-note { font-size: .75rem; color: var(--muted); font-weight: 400; line-height: 1.35; margin-top: 1px; overflow-wrap: anywhere; }
.cell-filled { background: var(--card); }
.cell-open { background: var(--card); }
.cell-na { background: var(--surface2); }
.cell-hint { color: var(--muted); font-size: .75rem; border: 1px dashed var(--border); border-radius: 999px; padding: 1px 9px; display: inline-block; }
/* Sold-out join text (green on card) - darker ink for contrast */
.cell-join {
  display: block; width: 100%; padding: 4px 8px;
  border: 1px dashed var(--esn-green); border-radius: var(--r-sm);
  background: transparent;
  font-family: inherit; font-size: .75rem; font-weight: 700; cursor: pointer;
  transition: background var(--t-fast) ease, color var(--t-fast) ease;
  white-space: nowrap;
  touch-action: manipulation;
  -webkit-user-select: none;
  user-select: none;
  border-color: var(--green-text);
  min-height: 30px;
  color: var(--green-text);
}
.cell-join:hover { background: var(--esn-green); color: var(--on-bright); }
.cell-join[data-role="board"]:hover { background: var(--esn-cyan); color: var(--on-bright); }
.cell-assign:hover { background: var(--esn-dark); border-color: var(--esn-dark); color: #fff; }
.chip-x {
  border: none; background: none;
  font-size: .8rem; font-weight: 700; cursor: pointer;
  font-family: inherit; line-height: 1; display: inline-flex; align-items: center; justify-content: center; padding: 0 4px; border-radius: 50%; color: var(--magenta-text); min-width: 30px; min-height: 30px; margin: -6px -8px -6px 0;
}
.grid-actions { display: inline-flex; white-space: nowrap; gap: 6px; }
.grid-ib {
  border: none; background: none; cursor: pointer; color: var(--muted);
  padding: 3px 4px; border-radius: 6px; line-height: 1; touch-action: manipulation; -webkit-user-select: none; user-select: none;
}
.grid-ib:hover { background: var(--surface2); color: var(--ink); }
.grid-ib.danger:hover { color: var(--esn-magenta); }
/* compact add/edit shift form */
.shift-form { display: grid; grid-template-columns: 1.6fr 112px 112px 1.2fr 72px 72px minmax(130px, auto); gap: 10px 12px; margin-top: 10px; align-items: end; }
/* task · from · until · time note · board · vol · button (1.1.15) */
.shift-form .shift-form-note { grid-column: 1 / -2; }
.shift-form .shift-form-btn { grid-column: -2 / -1; }
.shift-form .shift-form-btn .btn { white-space: nowrap; width: 100%; }
.shift-form .form-field { margin: 0; min-width: 0; }
.shift-form .form-field input { width: 100%; min-width: 0; }
.shift-form .form-field label { font-size: .75rem; }
.shift-form-card.editing { border-left: 4px solid var(--esn-orange); }
.grid-actions .btn, .grid-actions button { min-width: 32px; min-height: 32px; padding: 4px 6px; }  /* 1.14.1: one button */
.cell-join[data-role="board"] { color: var(--accent-text); border-color: var(--accent-text); }  /* 1.29.4: one system */
@media (max-width: 820px) {
  .shift-grid-wrap { scrollbar-width: none; }  /* v0.109.1: Design pass — playbook fundamentals */
  .shift-grid-wrap::-webkit-scrollbar { display: none; }
}
@media (max-width: 720px) {
  .shift-form { grid-template-columns: 1fr 1fr; }
  .shift-form .form-field:first-child { grid-column: 1 / -1; }
  .shift-form .shift-form-note { grid-column: 1 / -1; }
  .shift-form .shift-form-btn { grid-column: 1 / -1; }
  .shift-form .shift-form-btn .btn { width: 100%; }
  .shift-grid td { min-width: 78px; }
}

/* ============================================================
   v0.97 — #/links: the app's own link-in-bio page
   ============================================================ */
/* /links in its own frame (1.1.17): the Instagram-bio page */
body.links-page .site-header, body.links-page .site-footer, body.links-page .bottom-nav, body.links-page #beta-banner { display: none !important; }  /* 1.1.15: Settings markers */
body.links-page { padding-bottom: 0; }
body.links-page #app { padding-top: 18px; }
.links-page { max-width: 480px; margin: 18px auto 40px; }
.links-hero { text-align: center; margin-bottom: 18px; }
.links-hero img { width: 76px; height: 76px; border-radius: 20px; box-shadow: var(--shadow); }
.links-hero h1 { font-size: 1.45rem; font-weight: 900; margin: 10px 0 2px; }
.links-hero p { color: var(--muted); font-size: .9rem; margin-bottom: 10px; }
.links-hero .socials-row { justify-content: center; }
.links-sect {
  font-size: .8rem;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: .8px;
  color: var(--muted);
  margin: 20px 0 8px;
  text-align: center;
}
.link-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 100%;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  box-shadow: var(--shadow);
  padding: 14px 16px;
  margin-bottom: 10px;
  font-weight: 700;
  font-size: .9rem;
  color: var(--ink);
  text-decoration: none;
  transition: transform .15s, box-shadow .15s, background .15s;
}
.link-btn:hover { text-decoration: none; transform: translateY(-2px); box-shadow: var(--shadow-lg); background: var(--hover); }
.link-btn:active { transform: scale(.98); }
.link-btn .material-symbols-rounded { color: var(--esn-cyan); }
/* event rows inside the links page */
.link-event { justify-content: flex-start; border-left: 4px solid var(--accent, var(--esn-cyan)); text-align: left; }
.link-date {
  display: flex; flex-direction: column; align-items: center;
  min-width: 44px; padding: 4px 6px;
  background: var(--accent, var(--esn-cyan));
  background: color-mix(in srgb, var(--accent, var(--esn-cyan)) 62%, #000);  /* 1.55.0: deep enough for white text (cyan was 2.5:1) */
  color: #fff; border-radius: 10px; line-height: 1.1;
}
.link-date .d { font-size: 1.15rem; font-weight: 900; }
.link-date .m { font-size: .75rem; font-weight: 800; text-transform: uppercase; }
.link-ev-main { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.link-ev-main strong { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }  /* 1.78.4: two lines, not a cut title */
.link-ev-main small { color: var(--muted); font-size: .75rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.link-ev-price { font-size: .8rem; font-weight: 800; color: var(--cyan-text); white-space: nowrap; }  /* 1.78.4: 4.7:1 */
.links-seal {
  margin: 26px auto 8px; display: flex; flex-direction: column;
  align-items: center; gap: 8px; opacity: .9;
}  /* Passport cover (v0.108 redesign) */
.links-seal img { width: 72px; height: auto; }
.links-seal span { font-size: .75rem; color: var(--muted); letter-spacing: .04em; }
.link-ev-ico { display: inline-flex; align-items: center; margin-right: 2px; }  /* 1.1.33: Event icons */

/* ============================================================
   v0.98 — Cantus Codex (#/codex)
   ============================================================ */
.codex-page { max-width: var(--w-read); margin: 0 auto; }
.codex-song {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  box-shadow: var(--shadow);
  margin-bottom: 8px;
  padding: 0 14px;
}
.codex-song summary {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 13px 0;
  cursor: pointer;
  list-style: none;
  font-weight: 700;
}
.codex-song summary::-webkit-details-marker { display: none; }
.codex-num {
  min-width: 30px;
  text-align: center;
  font-size: .85rem;
  font-weight: 800;
  background: var(--hover);
  border-radius: var(--r-sm);
  padding: 4px 0;
  color: var(--accent-text);
}
.codex-title { flex: 1; min-width: 0; }
.codex-song { position: relative; }
.codex-tools { position: absolute; top: 9px; right: 0; display: flex; align-items: center; gap: 2px; }  /* 1.78.4: buttons inside a <summary> are a nested control for a screen reader */
.codex-song summary { padding-right: 76px; }
.codex-editbtn {
  border: none; background: none; cursor: pointer;
  color: var(--muted); padding: 4px;
}
.codex-editbtn:hover { color: var(--esn-cyan); }
.codex-lyrics {
  font-family: inherit;
  font-size: .95rem;
  line-height: 1.65;
  white-space: pre-wrap;
  margin: 4px 0 16px;
  color: var(--ink);
}
.codex-song[open] { border-left: 4px solid var(--esn-cyan); }
/* Codex tools (1.1.14) */
.codex-tools { display: flex; align-items: center; gap: 8px; margin: 0 0 12px; }
.codex-tools .filter-chips { flex: 1; min-width: 0; }
.codex-size { display: inline-flex; gap: 4px; flex: none; }
.codex-fav { background: none; border: 0; cursor: pointer; color: var(--muted); line-height: 1; min-width: 34px; min-height: 34px; display: inline-flex; align-items: center; justify-content: center; padding: 0; border-radius: 50%; }
.codex-fav.on { color: var(--esn-magenta); }
.codex-fav.on .material-symbols-rounded { font-variation-settings: "FILL" 1; }
.codex-song > summary { display: flex; align-items: center; gap: 8px; }
.codex-song .codex-title { flex: 1; min-width: 0; }
.codex-melody { display: flex; align-items: center; gap: 4px; }
/* Cantus mode (1.54.0): the page goes dark whatever the app theme, lyrics
   grow, chips and hearts step aside and the screen stays on. The dark
   variables are redefined on the root so cards, inputs and borders follow. */
#codex-cantus[aria-pressed="true"] { background: var(--esn-cyan); border-color: var(--esn-cyan); color: #fff; }
.codex-cantus {
  --ink: #e8e9f6; --muted: #9b9ec0; --bg: #12132a; --card: #1b1d3d; --border: #2d3057;
  --surface2: #22244a; --hover: #22244a; --accent-text: var(--esn-cyan); --shadow: 0 1px 3px rgba(0, 0, 0, .5);
  max-width: none; margin: 0 -24px; padding: 4px 24px 32px; min-height: calc(100vh + 90px);  /* past the body's bottom-nav padding, so no light strip shows at the end */
  background: var(--bg); color: var(--ink); color-scheme: dark;
}
.codex-cantus > * { max-width: var(--w-read); margin-left: auto; margin-right: auto; }
.codex-cantus .btn-ink, .codex-cantus a { color: var(--ink); }
.codex-cantus .codex-lyrics { font-size: 1.3em; }
.codex-cantus .filter-chips, .codex-cantus .codex-fav { display: none; }
@media (max-width: 820px) {
  .codex-cantus { margin: 0 -16px; padding: 4px 16px 32px; }  /* the phone gutter is 16px: bleed to the edge there too */
}
@media (max-width: 640px) {
  /* 1.54.0: the codex chips ran under the A- / A+ buttons, because the
     bleeding scroller kept its negative margin inside the tools row. On a
     phone the chips take a row of their own and simply wrap. */
  .codex-tools { flex-wrap: wrap; }
  .codex-tools > .filter-chips { flex: 1 1 100%; flex-wrap: wrap; overflow: visible; margin: 0; padding: 0; -webkit-mask-image: none; mask-image: none; }
  /* 1.76.0: the globe's rows wrap too; a scroller that runs under the card edge hid the Off chip */
  .globe-frow .filter-chips, .globe-bar-sub .filter-chips { flex-wrap: wrap; overflow: visible; margin: 0; padding: 0; -webkit-mask-image: none; mask-image: none; }
}

/* ============================================================
   v0.99 — cash register counting
   ============================================================ */
.cash-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 6px 18px; }
.cash-row { display: flex; align-items: center; gap: 10px; }
.cash-val { min-width: 62px; font-weight: 800; font-size: .9rem; text-align: right; color: var(--muted); }
.cash-row input { width: 76px; text-align: center; }
.cash-line { flex: 1; text-align: right; font-size: .85rem; font-weight: 700; color: var(--esn-cyan); font-variant-numeric: tabular-nums; }
.cash-total { text-align: right; font-size: 1.05rem; margin-top: 12px; }
.cash-total strong { color: var(--esn-green); font-size: 1.15rem; }

/* ---- v0.100: news, passport, guide, deals ---- */
/* One link, one button: the link is a stretched overlay so the dismiss
   button is a real sibling instead of a <button> inside an <a>. */
.news-strip {
  display: flex; align-items: center; gap: 12px;
  background: var(--card); border: 1px solid var(--border);
  border-left: 4px solid var(--esn-magenta); border-radius: var(--r-md);
  padding: 10px 14px; margin: 0 0 18px; text-decoration: none; color: var(--ink); position: relative;
}
.news-strip:hover { background: var(--hover); }
.news-strip-img { width: 52px; height: 52px; object-fit: cover; border-radius: var(--r-sm); flex: 0 0 52px; }
.news-strip-icon { color: var(--esn-magenta); }
.news-strip-main { min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.news-strip-main small { color: var(--muted); font-size: .75rem; }
.news-strip-main strong { font-size: .95rem; overflow: hidden; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; }  /* 1.69.6: two lines, not one */
.news-strip .chev { margin-left: auto; color: var(--muted); }
.news-img { width: calc(100% + 40px); margin: -20px -20px 12px; display: block; max-height: 260px; object-fit: cover; }
.passport-head { display: flex; align-items: center; gap: 12px; margin-bottom: 16px; }
.passport-head img { width: 46px; height: 46px; }
.news-card { padding: 0; overflow: hidden; margin: 0; display: flex; flex-direction: column; }  /* v1.5.0: audit */
/* The install pitch was clipped mid-word by the strip's nowrap rule. */
.news-strip-main strong.wrap {
  white-space: normal;
  overflow: visible;
  text-overflow: clip;
}  /* 1.1.35: Homepage audit fixes */
@media (min-width: 821px) {
  .news-card.news-latest { grid-column: 1 / -1; flex-direction: row; }  /* v1.5.0: audit */
}

/* ---------- Passport cover (v0.108 redesign) ---------- */
.pp-cover-stats b {
  font-variant-numeric: tabular-nums;
  display: block;
  white-space: nowrap;
  font-size: 1.15rem;
}  /* v0.109.1: Design pass — playbook fundamentals */
/* Deliberately one dark ESN-blue look in BOTH themes — it's the brand. */
.pp-cover {
  background: var(--navy-gradient);
  color: #fff;
  position: relative; overflow: hidden; margin-bottom: 18px;
  border: 1px solid rgba(255, 255, 255, .12);
  margin-top: 10px;
  padding: 20px 20px 18px;
  border-radius: 22px;
  box-shadow: 0 18px 40px rgba(30, 32, 90, .28);
}
.pp-cover::before {
  content: ""; position: absolute; inset: 0 0 auto 0; height: 5px;
  background: linear-gradient(90deg, var(--esn-dark) 20%, var(--esn-cyan) 20% 40%, var(--esn-magenta) 40% 60%, var(--esn-green) 60% 80%, var(--esn-orange) 80%);
}
/* The section's crest (1.3.0). One inline SVG, coloured by `color`, so it can
   be a faint watermark here and a solid mark elsewhere. It is never the app
   logo: the logo identifies the app, the crest identifies ESN Gent. */
.crest { display: inline-flex; line-height: 0; max-width: 100%; }
.crest svg { width: 100%; height: auto; max-width: 100%; display: block; }
/* Watermark on the passport cover: small, faint, behind everything. The caps
   below are deliberate belt and braces - 1.3.0 shipped a stylesheet that could
   arrive a release behind app.js, and an unstyled inline SVG expands to fill
   its parent, so the mark blew up to the full width of the page. The SVG now
   also carries its own width/height, so the worst case is a small shield. */
.crest-wm {
  position: absolute; right: -22px; top: -14px;
  width: 104px; max-width: 30%; height: auto; max-height: 100%;
  color: #fff; opacity: .07; pointer-events: none; z-index: 0;
}
.pp-cover > *:not(.crest-wm) { position: relative; z-index: 1; }
/* The seal at the foot of the public link page - full colour, because that
   page is the section's shopfront rather than a screen inside the app. */
.pp-cover-head { display: flex; align-items: center; gap: 12px; margin: 4px 0 14px; position: relative; }
.pp-cover-logo { width: 42px; height: auto; }
.pp-cover-kicker { display: block; font-size: .75rem; font-weight: 800; letter-spacing: .16em; color: rgba(255, 255, 255, .6); }
.pp-cover-head h2 { margin: 0; font-size: 1.3rem; color: #fff; }
.pp-cover-id { display: flex; align-items: center; gap: 14px; position: relative; margin-bottom: 6px; }
.pp-cover-id .pp-level-ring span { background: #20235f; color: #fff; }
.pp-cover-name { display: block; font-size: 1.15rem; }
.pp-cover-level { display: block; font-weight: 800; font-size: .85rem; margin-top: 2px; }
.pp-cover-xp { display: block; font-size: .75rem; color: rgba(255, 255, 255, .65); margin-top: 2px; }
.pp-cover-stats { display: grid; grid-template-columns: repeat(5, 1fr); position: relative; gap: 8px; }
.pp-cover-actions { display: flex; gap: 6px; flex: none; }
/* The five tiles deal themselves in. --i is set per tile in the markup. */
.pp-cover-stats > div {
  background: rgba(255, 255, 255, .08); border: 1px solid rgba(255, 255, 255, .14); text-align: center; min-width: 0; animation: pp-tile-in .5s cubic-bezier(.22, 1, .36, 1) both; animation-delay: calc(.45s + var(--i, 0) * .07s); padding: 10px 6px; border-radius: var(--r-md);
}
.pp-cover-stats span { font-size: .75rem; text-transform: uppercase; letter-spacing: .05em; color: rgba(255, 255, 255, .6); }
.pp-cover-hint { margin: 12px 0 0; font-size: .75rem; color: rgba(255, 255, 255, .55); position: relative; margin-top: 12px; }
/* Month bundles for the stamp collection */
.pp-month {
  border: 1px solid var(--border); border-radius: var(--r-md);
  padding: 10px 14px; margin-bottom: 10px; background: var(--card);
}
.pp-month summary { cursor: pointer; display: flex; justify-content: space-between; align-items: center; gap: 10px; list-style: none; }
.pp-month summary::-webkit-details-marker { display: none; }
.pp-month[open] summary { margin-bottom: 12px; }
.stamp-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(96px, 1fr));
  gap: 10px;
  margin-bottom: 14px;
}
/* Stamps land like stamps: oversized, a bounce as they hit, then settled.
   The rotation is the one each stamp already had, kept through every frame
   so they do not spin on the way in. */
/* stamp marks and crew stamps */
.stamp {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  aspect-ratio: 1; border: 2.5px dashed var(--stamp); border-radius: 50%;
  color: var(--stamp); text-decoration: none; text-align: center;
  transform: rotate(var(--tilt)); background: var(--card);
  transition: transform .15s ease;
  padding: 6px;
  border-width: 2px;
  animation: pp-stamp-in .52s cubic-bezier(.3, 1.4, .5, 1) both;
  animation-delay: calc(var(--i, 0) * .055s);
  position: relative;
  font: inherit; cursor: pointer; /* 1.78.16: a button now (it opens the stamp's share) */
}
.stamp:hover { transform: rotate(0deg) scale(1.05); }
.stamp.is-opening { opacity: .55; }
.stamp-date { font-weight: 900; text-transform: uppercase; letter-spacing: .5px; font-size: .75rem; }
.stamp-title { line-height: 1.25; margin-top: 3px; color: var(--ink); overflow: hidden; font-size: .75rem; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
.pp-badge {
  background: var(--card); border: 1px solid var(--border); text-align: center; display: flex; flex-direction: column; gap: 3px; padding: 12px 8px 10px; border-radius: var(--r-md); opacity: 1;
}
/* An earned badge gets a shine sweep; a locked one stays flat and quiet. */
.pp-badge.earned { opacity: 1; position: relative; overflow: hidden; border-color: var(--border); }
.pp-badge-icon { font-size: 1.7rem; }
.pp-badge strong { font-size: .8rem; }
.pp-badge small { font-size: .75rem; color: var(--muted); }
/* Passport stamps: the event's material icon inside the stamp */
.stamp-ico .material-symbols-rounded { font-size: 1.45rem; line-height: 1; }  /* v0.125 */
.stamp .stamp-ico { margin-bottom: 2px; }
/* Passport badges as Material icons */
.pp-badge-icon .material-symbols-rounded { font-size: 28px; color: var(--accent-text); }  /* v1.1.6: Home */
html[data-theme="dark"] .pp-badge-icon .material-symbols-rounded { color: var(--esn-cyan); }
.pp-badge.earned .pp-badge-icon .material-symbols-rounded { color: var(--esn-magenta); }
.pp-badge-icon.is-locked .material-symbols-rounded, .pp-badge-icon.is-secret .material-symbols-rounded { color: var(--muted); opacity: .7; }
.stamp .stamp-ico .material-symbols-rounded { font-size: 20px; }  /* 1.1.7: passport structure + denser stamps */
.stamp:active { transform: rotate(0deg) scale(.96); }  /* 1.7.0: ESN Passport motion */
.pp-badge.earned::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(105deg, transparent 38%, rgba(122, 193, 67, .28) 50%, transparent 62%);
  transform: translateX(-120%);
  animation: pp-shine 4.5s calc(1.2s + var(--i, 0) * .25s) ease-in-out infinite;
}
/* The badge that was just earned announces itself once. */
.pp-badge.pp-fresh { animation: pp-badge-pop .7s cubic-bezier(.34, 1.56, .64, 1) both; border-color: var(--esn-green); }
.pp-cover.pp-gold { background: linear-gradient(160deg, #5a4500, #8a6a08 45%, #3b2d00); border-color: rgba(255,215,94,.45); }  /* 1.17.0: ESN Passport 2.0 */
.pp-cover.pp-gold::before { background: linear-gradient(90deg, #ffd75e, #EAB308 50%, #ffd75e); }
.pp-badge.rar-rare.earned { border-color: var(--esn-cyan); }
.pp-badge.rar-epic.earned { border-color: var(--esn-magenta); }
.pp-badge.rar-legendary.earned { border-color: #EAB308; box-shadow: 0 0 0 3px rgba(234,179,8,.18); }
/* Stamps on paper. */
.stamp-page { position: relative; padding: 14px 12px 8px; margin-bottom: 18px; border-radius: 6px 16px 16px 6px; background: #fbf7ee; border: 1px solid #e6dfcc; box-shadow: inset 12px 0 18px -14px rgba(0,0,0,.25), 0 8px 22px rgba(30,32,90,.1); }
.stamp-page .stamp-grid { margin-bottom: 6px; }
.stamp-page .stamp { background: transparent; border-style: double; border-width: 4px; mix-blend-mode: multiply; }
.stamp.is-gold { border-color: #EAB308; box-shadow: 0 0 0 4px rgba(234,179,8,.18); }
.stamp.is-ghost { border-style: dashed; border-width: 2.5px; border-color: var(--muted); color: var(--muted); opacity: .8; }
.stamp-page-foot { margin: 0; font-size: .75rem; color: #a89f86; text-align: center; }
.pp-badge:not(.earned) strong { color: var(--muted); }  /* 1.17.1: passport polish */
.pp-cover-stats.six { grid-template-columns: repeat(6, 1fr); }  /* 1.29.0: passport 3 */
.stamp-marks { position: absolute; top: -6px; right: -6px; display: flex; gap: 2px; z-index: 1; }
.stamp-mark { width: 22px; height: 22px; border-radius: 50%; background: var(--card); border: 1.5px solid var(--stamp); color: var(--stamp); display: flex; align-items: center; justify-content: center; }
.stamp-mark .material-symbols-rounded { font-size: 14px; }
.stamp.is-crew { border-style: solid; border-width: 3px; }
@media (min-width: 821px) {
  .stamp-grid { grid-template-columns: repeat(auto-fill, minmax(104px, 1fr)); }  /* 1.1.7: passport structure + denser stamps */
}
@media (max-width: 640px) {
  .stamp-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }  /* 1.78.16: minmax(0): a round stamp's content made each column 140px, so the third ran off a phone */
  .stamp-title { font-size: .75rem; }
}
@media (max-width: 520px) {
  .crest-wm { width: 84px; right: -18px; top: -12px; }
}
@media (max-width: 480px) {
  .pp-cover-stats { grid-template-columns: repeat(6, 1fr); }
  .pp-cover-stats > div { grid-column: span 2; }
  .pp-cover-stats > div:nth-child(n+4) { grid-column: span 3; }
  .pp-cover-head { flex-wrap: wrap; }
  .pp-cover-actions { width: 100%; justify-content: flex-end; }
  .pp-cover-stats.six > div, .pp-cover-stats.six > div:nth-child(n+4) { grid-column: span 2; }  /* 1.29.0: passport 3 */
}

/* ---------- Account: passport level card (v0.124) ---------- */
/* Users tab: Last seen only on wide screens */
/* Account: compact level strip */
.pp-level-strip {
  display: flex; align-items: center;
  background: var(--card); border: 1px solid var(--border); border-radius: var(--r-md);
  color: inherit; text-decoration: none; cursor: pointer; margin: 8px 2px 2px; padding: 8px 12px; gap: 10px;
}
a.pp-level-strip:hover { text-decoration: none; border-color: var(--esn-cyan); }
.pp-strip-cta { flex: none; display: inline-flex; align-items: center; gap: 2px; font-size: .8rem; font-weight: 800; color: var(--esn-dark); white-space: nowrap; }
html[data-theme="dark"] .pp-strip-cta { color: var(--esn-cyan); }
.pp-strip-cta .material-symbols-rounded { font-size: 16px; }
.pp-strip-ring {
  position: relative; border-radius: 50%; flex: none;
  display: flex; align-items: center; justify-content: center; width: 36px; height: 36px;
}
.pp-strip-ring img, .pp-strip-ring b { border-radius: 50%; object-fit: cover;
  display: flex; align-items: center; justify-content: center;
  background: var(--card); font-size: .95rem; width: 30px; height: 30px;
}
.pp-strip-ring i {
  position: absolute; right: -3px; bottom: -3px;
  width: 18px; height: 18px; border-radius: 50%;
  color: #fff; font-style: normal; font-weight: 800; font-size: .75rem;
  display: flex; align-items: center; justify-content: center;
  border: 2px solid var(--card);
}
.pp-strip-main small { font-size: .75rem; color: var(--muted); }
.pp-level-strip .chev { color: var(--muted); font-size: 1.3rem; }
/* Level-coloured contour & shine on the card replica — grows with level */
.pp-glow-2 .esncard { box-shadow: 0 0 0 2px rgba(0, 174, 239, .45), 0 6px 22px rgba(0, 174, 239, .22); }
.pp-glow-3 .esncard { box-shadow: 0 0 0 2px rgba(122, 193, 67, .55), 0 6px 26px rgba(122, 193, 67, .28); }
.pp-glow-4 .esncard { box-shadow: 0 0 0 3px rgba(244, 123, 32, .6), 0 8px 30px rgba(244, 123, 32, .34); }
.pp-glow-5 .esncard { box-shadow: 0 0 0 3px rgba(236, 0, 140, .7), 0 10px 36px rgba(236, 0, 140, .4); animation: ppGlowPulse 2.8s ease-in-out infinite; }
/* Tiered badges (v0.116): mini progress bar toward the next tier */
.pp-badge-bar { display: block; height: 4px; border-radius: 2px; background: rgba(128, 128, 160, .28); margin-top: 6px; overflow: hidden; }
.pp-badge-bar i { display: block; height: 100%; border-radius: 2px; background: var(--esn-cyan); width: 100%; transform: translateX(calc(var(--p, 0%) - 100%)); transition: transform .4s ease; }
.pp-strip-main strong { font-size: .9rem; display: flex; align-items: baseline; gap: 6px; flex-wrap: wrap; }
.pp-strip-main strong small { font-weight: 500; }
.pp-strip-main { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; }  /* 1.18.1: the passport on the home screen */
.pp-strip-main > small { font-size: .75rem; letter-spacing: .8px; text-transform: uppercase; color: rgba(255, 255, 255, .62); }
.pp-strip-main > strong { font-size: 1rem; font-weight: 800; }
@media (max-width: 820px) {
  .pp-level-strip { order: 0; }
}
@media (max-width: 420px) {
  .pp-strip-main > strong { font-size: .95rem; }  /* 1.18.1: the passport on the home screen */
}
@media (max-width: 400px) {
  .pp-strip-cta .cta-word { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  .pp-glow-5 .esncard { animation: none; }
}

/* ---------- Guide (v0.100) ---------- */
.guide-item {
  display: flex; gap: 10px; padding: 7px 8px;
  border-radius: var(--r-sm); cursor: pointer; font-size: .9rem; min-height: 44px; align-items: flex-start;
}
.guide-item:hover { background: var(--hover); }
.guide-item input { margin-top: 1px; width: 22px; height: 22px; flex: none; accent-color: var(--esn-green); cursor: pointer; }
.guide-item:has(input:focus-visible) { outline: var(--ring); outline-offset: 2px; border-radius: var(--r-sm); }
.guide-item.done > span { color: var(--muted); text-decoration: line-through; text-decoration-color: color-mix(in srgb, var(--muted) 50%, transparent); }
.guide-item.done span { text-decoration: line-through; color: var(--muted); }
.guide-line { margin: 4px 0; font-size: .9rem; }

/* ---- 1.18.0: the guide as chapters ---- */
.guide { max-width: var(--w-read); margin: 0 auto; }
.guide-hero { display: flex; align-items: center; gap: 16px; margin: 14px 0 14px; padding: 16px 18px; border-radius: 18px; color: #fff; background: linear-gradient(135deg, #22246e 0%, var(--esn-dark) 55%, var(--esn-cyan) 150%); box-shadow: var(--shadow); }
.guide-hero-main { min-width: 0; flex: 1; }
.guide-hero .section-title { color: #fff; font-size: 1.15rem; }
.guide-hero .section-title::before { display: none; }
/* The route lands focus on the title: no black ring inside the gradient
   (keyboard focus keeps the shared :focus-visible ring). */
.guide-hero .form-hint { color: rgba(255, 255, 255, .8); font-size: .8rem; }
@media (max-width: 380px) {
  .guide-hero { flex-wrap: wrap; }
}
.guide-ring { --pct: 0; width: 68px; height: 68px; border-radius: 50%; flex: none; background: conic-gradient(var(--esn-green) calc(var(--pct) * 1%), rgba(255, 255, 255, .22) 0); display: flex; align-items: center; justify-content: center; position: relative; }
.guide-ring::before { content: ""; position: absolute; inset: 7px; border-radius: 50%; background: var(--esn-dark); }
.guide-ring span { position: relative; font-size: .9rem; font-weight: 900; color: #fff; }
.guide-pick { display: flex; align-items: center; gap: 12px; width: 100%; text-align: left; margin: 0 0 14px; padding: 12px 14px; border-radius: var(--r-lg); border: 1px solid var(--border); background: var(--card); color: var(--ink); font: inherit; cursor: pointer; }
.guide-pick:hover { border-color: var(--esn-cyan); }
.guide-pick-ic { width: 44px; height: 44px; border-radius: var(--r-md); background: var(--hover); display: flex; align-items: center; justify-content: center; flex: none; }
.guide-pick-ic .material-symbols-rounded { color: var(--esn-magenta); font-size: 24px; }
.guide-pick-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.guide-pick-main small { font-size: .75rem; letter-spacing: 1px; text-transform: uppercase; color: var(--muted); font-weight: 700; }
.guide-chapters { display: flex; flex-direction: column; gap: 10px; }
.guide-chapter { border: 1px solid var(--border); border-radius: var(--r-lg); background: var(--card); overflow: hidden; }
.guide-chapter > summary { list-style: none; display: flex; align-items: center; gap: 12px; padding: 12px 14px; cursor: pointer; }
.guide-chapter > summary::-webkit-details-marker { display: none; }
.guide-chapter[open] > summary { border-bottom: 1px solid var(--border); }
.guide-chapter > summary .chev { color: var(--muted); transition: transform .2s ease; }
.guide-chapter[open] > summary .chev { transform: rotate(90deg); }
.guide-ch-ic { width: 42px; height: 42px; border-radius: 13px; background: var(--hover); display: flex; align-items: center; justify-content: center; flex: none; }
.guide-ch-ic .material-symbols-rounded { color: var(--esn-dark); font-size: 24px; }
html[data-theme="dark"] .guide-ch-ic .material-symbols-rounded { color: var(--esn-cyan); }
.guide-ch-ic.full { background: color-mix(in srgb, var(--esn-green) 18%, transparent); }
.guide-ch-ic.full .material-symbols-rounded { color: var(--esn-green); }
.guide-ch-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.guide-ch-main strong { font-size: 1rem; }
.guide-ch-main small { font-size: .75rem; color: var(--muted); }
.guide-ch-bar { height: 6px; border-radius: 999px; background: var(--border); overflow: hidden; }
.guide-ch-bar i { display: block; height: 100%; background: linear-gradient(90deg, var(--esn-cyan), var(--esn-green)); }
.guide-ch-body { padding: 8px 10px 10px; }
.guide-intro { padding: 4px 4px 8px; }
.guide-chapter .guide-item { padding: 10px 8px; border-radius: 10px; gap: 12px; }
.guide-chapter .guide-item + .guide-item { border-top: 1px solid var(--border); border-radius: 0; }

/* ---------- Deals (v0.100) ---------- */
.deals-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(240px, 100%), 1fr)); gap: 14px; }  /* 1.69.6: never wider than a narrow (or big-text) screen */
.deal-card {
  background: var(--card); border: 1px solid var(--border);
  padding: 14px; display: flex; flex-direction: column; gap: 8px; position: relative; border-radius: var(--radius);
  cursor: pointer; transition: border-color var(--t-fast) ease, box-shadow var(--t-fast) ease;
}
.deal-card:hover { border-color: var(--esn-cyan); box-shadow: var(--shadow); }
.deal-card.promoted { border-color: var(--esn-orange); box-shadow: 0 2px 12px rgba(244, 123, 32, .18); }
.deal-card[data-quiet] { border-style: dashed; }  /* 1.78.4: a partner not active any more (was opacity .75 on the whole card, under AA) */
.deal-flag { font-size: .7rem; font-weight: 800; text-transform: uppercase; letter-spacing: .5px; color: var(--orange-text); }
.deal-head { display: flex; align-items: center; gap: 10px; }
.deal-logo { width: 44px; height: 44px; border-radius: 10px; object-fit: cover; flex: 0 0 44px; }
.deal-logo-ph { display: flex; align-items: center; justify-content: center; color: #fff; font-weight: 900; font-size: 1.15rem; background: var(--c, var(--esn-dark)); }
.deal-text { font-size: .9rem; margin: 0; }
.deals-hero { margin: 0 0 14px; }  /* 1.13.0: the deals page students want to scroll; 1.78.13: one compact card, the numbers in a line */
.deals-hero-sum { font-size: 1.05rem; }
.deals-hero-split { font-size: .9rem; }
.deals-hero-split::before { content: "· "; }
@media (max-width: 720px) { .deals-hero-split { display: block; } .deals-hero-split::before { content: none; } }  /* the numbers on a line of their own on a phone */
.deals-tools { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin: 0 0 10px; }  /* 1.78.13: search, and List | Map on a phone */
.deals-search { flex: 1 1 260px; display: flex; align-items: center; gap: 8px; min-height: 44px; padding: 0 14px; border: 1px solid var(--border); border-radius: 999px; background: var(--card); color: var(--muted); }
.deals-search:focus-within { border-color: var(--esn-cyan); box-shadow: 0 0 0 3px rgba(0, 174, 239, .2); }
.deals-search input { flex: 1; min-width: 0; border: 0; background: transparent; color: var(--ink); font: inherit; font-size: 1rem; padding: 10px 0; outline: none; }
.seg.deals-view { display: none; }  /* only on a phone (below) */
.deals-count { margin: 0 0 8px; }
.deals-count:empty { display: none; }
.deals-layout.has-map { display: grid; grid-template-columns: minmax(0, 1fr) minmax(300px, 380px); gap: 16px; align-items: start; }  /* the list and the map side by side */
.deals-side { position: sticky; top: calc(var(--bar-h, 64px) + 12px); }
.deals-layout.has-map .deals-map { height: min(560px, calc(100vh - 180px)); }
.deals-layout .group-title:first-child { margin-top: 0; }
.deal-foot { display: flex; align-items: center; gap: 8px; margin-top: auto; padding-top: 2px; }  /* where it is, the map, the way in */
.deal-where { flex: 1; min-width: 0; margin: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.deal-go { display: inline-flex; color: var(--muted); }
.deal-name-link { color: inherit; text-decoration: none; }
.deal-name-link:hover { text-decoration: underline; }
.deal-act { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px; min-height: 64px; padding: 10px 6px; border: 1px solid var(--border); border-radius: var(--r-md); background: var(--card); color: var(--ink); font: inherit; font-size: .8rem; font-weight: 700; text-decoration: none; cursor: pointer; }  /* 1.78.13: one row of actions on a partner's page */
.deal-act .material-symbols-rounded { font-size: 22px; color: var(--accent-text); }
.deal-act:hover { border-color: var(--esn-cyan); background: var(--hover); }
.deal-act:focus-visible { outline: 2px solid var(--esn-cyan); outline-offset: 2px; }
.deal-page-report { margin: 16px 0 0; }
.deals-more { margin: 0 0 10px; }
.deals-hero-cta { border-radius: var(--r-md); padding: 14px 16px; background: linear-gradient(135deg, rgba(0, 174, 239, .14), rgba(236, 0, 140, .08)); border: 1px solid var(--border); display: flex; flex-direction: column; justify-content: center; gap: 8px; }
.deals-hero-cta p { margin: 0; }
.deals-hero-cta .btn { align-self: flex-start; }
.deal-type-chips { margin: 0 0 12px; }
.deals-map-card { padding: 8px 8px 10px; margin: 0 0 14px; }
.deals-map { height: 300px; border-radius: 10px; overflow: hidden; background: var(--map-bg); }
.deals-map .leaflet-popup-content { font: inherit; font-size: .9rem; }
.deals-map .leaflet-popup-content .linklike { color: var(--accent-text); font-weight: 700; text-decoration: none; }
.deals-map .leaflet-popup-content .linklike:hover { text-decoration: underline; }
.deal-ribbon {
  position: absolute; top: 14px; right: -34px; width: 130px; padding: 4px 0; text-align: center;
  transform: rotate(38deg); background: var(--magenta-deep); color: #fff; font-size: .75rem; font-weight: 900;  /* 1.77.0: the deeper magenta carries white text at 5:1 */
  letter-spacing: .4px; text-transform: uppercase; box-shadow: 0 2px 8px rgba(0, 0, 0, .18); pointer-events: none;
  font-variant-numeric: tabular-nums;
}
.deal-ribbon.new { background: var(--esn-green); }
.deal-card.promoted .deal-ribbon { background: var(--esn-orange); color: var(--on-bright); }
.deal-logo-icon { overflow: hidden; }
.deal-logo-icon .material-symbols-rounded { font-size: 24px; }
.deal-name { display: flex; flex-direction: column; min-width: 0; padding-right: 26px; }
.deal-name small { font-size: .75rem; }
.deal-promo { margin: 0; font-size: .85rem; color: var(--muted); font-style: italic; }
.deal-card.deal-hilite { border-color: var(--esn-cyan); box-shadow: 0 0 0 3px rgba(0, 174, 239, .28); transition: box-shadow var(--t-slow) ease; }
.deal-page { max-width: var(--w-read); }  /* 1.14.0: a page per partner */
.deal-page-side .deals-map-card { margin: 0; }
@media (min-width: 1024px) {
  .deal-page { max-width: 1080px; }  /* 1.78.13: the deal on the left, the map and the actions beside it */
  .deal-page-body { display: grid; grid-template-columns: minmax(0, 1fr) 340px; gap: 20px; align-items: start; }
  .deal-page-side { position: sticky; top: calc(var(--bar-h, 64px) + 12px); display: flex; flex-direction: column; gap: 12px; }
  .deal-page-side .deal-page-actions { margin: 0; }
  .deal-page .deals-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
.deal-page-head { display: flex; align-items: center; gap: 14px; position: relative; margin: 0 0 14px; }
.deal-page-title { min-width: 0; flex: 1; }
.deal-page-title .section-title { font-size: 1.3rem; }
.deal-logo-lg { width: 64px; height: 64px; border-radius: var(--r-md); flex: 0 0 64px; }
.deal-logo-lg .material-symbols-rounded { font-size: 32px; }
.deal-page-ribbon { flex: 0 0 auto; background: var(--magenta-deep); color: #fff; font-weight: 900; font-size: .9rem; letter-spacing: .4px; padding: 6px 12px; border-radius: 999px; font-variant-numeric: tabular-nums; }
.deal-page-ribbon.new { background: var(--esn-green); }
.deal-page-deal { background: var(--card); border: 1px solid var(--border); border-left: 5px solid var(--esn-cyan); border-radius: var(--r-md); padding: 14px 16px; margin: 0 0 12px; }
.deal-page-label { margin: 0 0 4px; font-size: .75rem; font-weight: 800; letter-spacing: .5px; text-transform: uppercase; color: var(--muted); }
.deal-page-text { margin: 0; font-size: 1.05rem; font-weight: 700; white-space: pre-line; }
.deal-page-deal .deal-promo { margin-top: 8px; }
.deal-page-claim { background: linear-gradient(135deg, rgba(0, 174, 239, .14), rgba(236, 0, 140, .08)); border: 1px solid var(--border); border-radius: var(--r-md); padding: 12px 16px; margin: 0 0 12px; }
.deal-page-claim p { margin: 0; }
.deal-page-claim p + p { margin-top: 6px; }
.deals-map-one { height: 220px; }
.deal-page-actions { display: grid; grid-template-columns: repeat(auto-fit, minmax(92px, 1fr)); gap: 8px; margin: 12px 0 16px; }
.pd-report { white-space: pre-wrap; font: inherit; font-size: .9rem; background: var(--surface2); border: 1px solid var(--border); border-radius: 10px; padding: 12px 14px; margin: 0; }
.jacob-partner textarea { font: inherit; width: 100%; }
.jacob-partner .seg { display: inline-flex; border: 1px solid var(--border); border-radius: 999px; overflow: hidden; background: var(--surface2); }
.jacob-partner .seg button { border: 0; background: none; padding: 6px 12px; min-height: 0; font-family: inherit; font-size: .8rem; font-weight: 700; color: var(--muted); cursor: pointer; white-space: nowrap; }
.jacob-partner .seg button.active { background: var(--esn-dark); color: #fff; }
.jacob-partner .seg button:hover { background: var(--hover); }
.jacob-partner .seg button.active:hover { background: var(--esn-dark); }
/* Deals (1.1.14) */
.deal-clamp { display: -webkit-box; -webkit-line-clamp: 4; -webkit-box-orient: vertical; overflow: hidden; }
.deal-card .more-menu-list { right: 0; left: auto; }
/* 1.58.0: a map keeps its layers to itself: Leaflet's panes (z-index 400 to 1000) no longer float over the header and the menus */
.leaflet-container { isolation: isolate; z-index: 0; }
.deals-map.leaflet-container { background: var(--map-bg); }  /* 1.15.0: colours per category */
/* The ribbon clips inside its own box, so the card can let a menu overflow. */
.deal-ribbon-box { position: absolute; inset: 0; overflow: hidden; border-radius: inherit; pointer-events: none; }
.deal-card:has(.more-menu[open]) { z-index: 41; }
.deal-code { display: inline-block; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 1rem; font-weight: 700; letter-spacing: .5px; padding: 4px 10px; border-radius: var(--r-sm); background: var(--surface2); border: 1px dashed var(--border); color: var(--ink); }  /* 1.21.0: partner discount codes */
@media (max-width: 720px) {
  .deal-page-head { flex-wrap: wrap; }  /* 1.14.0: a page per partner */
  .deal-page-ribbon { order: 3; }
  .deals-map { height: 240px; }
}
@media (max-width: 1023px) {
  .deals-layout.has-map { display: block; }  /* 1.78.13: on a phone or a tablet, List or Map */
  .seg.deals-view { display: inline-flex; }
  .deals-layout[data-view="list"] .deals-side, .deals-layout[data-view="map"] .deals-main { display: none; }
  .deals-side { position: static; }
  .deals-layout.has-map .deals-map { height: max(320px, calc(100vh - 300px)); }
}

/* ---- 1.22.0: the partner form as a dialog, in four groups ---- */
.pt-dialog { margin: auto; border: 0; border-radius: 18px; padding: 0; width: min(920px, calc(100vw - 24px)); max-height: calc(100vh - 24px); background: var(--card); color: var(--ink); box-shadow: var(--shadow-lg); }
.pt-dialog::backdrop { background: rgba(18, 20, 56, .64); }  /* 1.69.5: no blur */
.pt-dialog-in { display: flex; flex-direction: column; max-height: calc(100vh - 24px); margin: 0; }
.pt-dialog-head { display: flex; align-items: center; gap: 10px; padding: 14px 18px; border-bottom: 1px solid var(--border); }
.pt-dialog-head h2 { margin: 0; font-size: 1.15rem; flex: 1; display: flex; align-items: center; gap: 8px; }
.pt-dialog-body { overflow: auto; padding: 6px 18px 12px; }
.pt-dialog-foot { padding: 12px 18px; border-top: 1px solid var(--border); margin: 0; }
.pt-sect { padding: 14px 0 6px; border-bottom: 1px dashed var(--border); }
.pt-sect:last-child { border-bottom: 0; }
.pt-sect-h { display: flex; align-items: center; gap: 8px; margin: 0 0 10px; font-size: .95rem; font-weight: 900; }
.pt-sect-h .material-symbols-rounded { color: var(--esn-cyan); }
.pt-sect-h .form-hint { font-weight: 500; }
.pt-sect .form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px 14px; }
.pt-sect .form-field.full { grid-column: 1 / -1; }
.pt-codes-field textarea { width: 100%; }
.pt-dialog .hint-pop { position: fixed; }
@media (max-width: 640px) {
  .pt-sect .form-grid { grid-template-columns: minmax(0, 1fr); }
  .pt-dialog { width: 100vw; max-height: 100vh; border-radius: 0; }
  .pt-dialog-in { max-height: 100vh; }
}

/* ---- 1.13.0: the deals page students want to scroll ---- */
.jacob-xs { width: 16px; height: 16px; vertical-align: -3px; margin-right: 2px; }

/* ---- v0.101: passport gamification ---- */
.pp-level-card {
  display: flex; align-items: center; gap: 14px;
  background: var(--card); border: 1px solid var(--lvl, var(--border));
  border-radius: var(--r-md); padding: 12px 16px; margin-bottom: 18px;
}
.pp-section > summary {
  cursor: pointer; list-style: none; display: flex; align-items: center;
  gap: 8px; flex-wrap: wrap; font-weight: 800; font-size: 1rem;
  padding: 12px 40px 12px 14px; background: var(--card); border: 1px solid var(--border);
  border-radius: var(--radius); position: relative;
}
.pp-section > summary::-webkit-details-marker { display: none; }
.pp-section > summary::after {
  content: "expand_more"; font-family: "Material Symbols Rounded";
  font-weight: 400; opacity: .6; transition: transform .2s;
  position: absolute; right: 12px; top: 50%; transform: translateY(-50%);
}
.pp-section[open] > summary::after { transform: translateY(-50%) rotate(180deg); }
.pp-section > summary .form-hint { font-weight: 400; }
.pp-section-body { padding-top: 10px; }
.pp-level-ring {
  width: 58px; height: 58px; border-radius: 50%; flex: 0 0 58px;
  display: flex; align-items: center; justify-content: center;
}
.pp-level-ring span {
  width: 44px; height: 44px; border-radius: 50%; background: var(--card);
  display: flex; align-items: center; justify-content: center;
  font-weight: 900; font-size: 1.15rem; color: var(--lvl, var(--ink));
}
.visa-grid { display: flex; flex-wrap: wrap; gap: 10px; margin-bottom: 6px; }
.visa {
  display: inline-flex; align-items: center; gap: 8px;
  border: 2px dashed var(--border); border-radius: 999px;
  padding: 7px 16px 7px 10px; font-size: .85rem; font-weight: 700;
  color: var(--muted); background: var(--card);
}
.visa.earned { border-style: solid; border-color: var(--visa); color: var(--visa); }
.visa-mark {
  width: 24px; height: 24px; border-radius: 50%; display: inline-flex;
  align-items: center; justify-content: center; font-size: .75rem;
  background: var(--hover); color: var(--muted);
}
.visa.earned .visa-mark { background: var(--visa); color: #fff; }
.league-row { display: flex; align-items: center; gap: 10px; padding: 7px 6px; border-radius: var(--r-sm); font-size: .9rem; }
.league-row.mine { background: var(--hover); font-weight: 800; }
.league-pos { width: 22px; text-align: right; color: var(--muted); font-weight: 800; }
.league-flag { font-size: 1.3rem; }
.league-name { min-width: 90px; }
.league-bar { flex: 1; height: 10px; border-radius: 5px; background: var(--hover); overflow: hidden; }
.league-bar i { display: block; height: 100%; border-radius: 5px; background: linear-gradient(90deg, var(--esn-cyan), var(--esn-dark)); }
.league-count { min-width: 40px; text-align: right; font-weight: 800; font-variant-numeric: tabular-nums; }
/* Collapsible passport sections (v0.136): visas, badges & co fold away so
   the passport stays a short scroll - the cover stats carry the overview. */
.pp-section { margin: 0 0 8px; }  /* 1.1.7: passport structure + denser stamps */

/* ---------- v0.125 ---------- */
/* Whole card is clickable (v0.136) - the JS delegated [data-evlink] handler */
[data-evlink] { cursor: pointer; }
.card-ribbon {
  position: absolute; top: 18px; right: -34px; z-index: 3;
  transform: rotate(38deg);
  background: var(--esn-magenta); color: #fff;
  font-size: .7rem; font-weight: 900; letter-spacing: .6px; text-transform: uppercase;
  padding: 5px 40px; box-shadow: 0 2px 8px rgba(0, 0, 0, .25);
  pointer-events: none;
}
/* Sold out and cancelled ride the same corner (1.8.0). A ribbon is readable
   while you scroll past; the badge down in the footer only is once you have
   stopped, which is too late to stop you tapping in. Magenta stays "hurry",
   so these get their own colours: grey for closed, red for called off. */
.card-ribbon.ribbon-out { background: #5f627a; }
/* Featured sits below the urgent states on purpose: if an event is nearly
   gone, that is the more useful thing to say about it. */
.card-ribbon.ribbon-pin { background: var(--esn-cyan); }
.card-ribbon.ribbon-off { background: var(--danger); }
html[data-theme="dark"] .card-ribbon.ribbon-out { background: #6e7189; }

/* ---------- Install page (1.78.9) ---------- */
/* the hero says what to do on this device; then the steps, notifications, perks, help */
.ins-hero { position: relative; overflow: hidden; display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 16px; align-items: center; margin: 0 0 16px; padding: 20px 18px 22px; border-radius: var(--radius); color: #fff; background: radial-gradient(circle at 15% 0%, #3a3fb0 0%, #2E3192 40%, #1a1d5e 100%); box-shadow: var(--shadow-lg); animation: ppl-in .5s cubic-bezier(.2, .7, .3, 1) both; }
.ins-hero-text { position: relative; z-index: 1; min-width: 0; }
#app h2.ins-title { margin: 0 0 6px; font-size: 1.3rem; font-weight: 900; line-height: 1.2; color: #fff; }  /* with the id: #app h2:not(.section-title) sets every other h2 */
.ins-lede { margin: 0 0 14px; max-width: 52ch; color: #e4e6fb; font-size: .9rem; line-height: 1.5; }
.ins-sub { margin: 0 0 12px; color: #e4e6fb; font-size: .85rem; line-height: 1.5; }
.ins-state { display: flex; align-items: flex-start; gap: 6px; margin: 0 0 10px; font-size: .9rem; font-weight: 700; line-height: 1.4; }
.ins-state.ok { color: #b9f18c; }
.ins-state.warn { color: #ffd27a; }
.ins-phone { position: relative; z-index: 1; width: 92px; height: 168px; padding: 20px 9px 10px; border: 2px solid rgba(255, 255, 255, .55); border-radius: 18px; background: rgba(10, 12, 50, .35); }
.ins-phone::before { content: ""; position: absolute; top: 8px; left: 50%; width: 26px; height: 4px; margin-left: -13px; border-radius: 4px; background: rgba(255, 255, 255, .4); }
.ins-screen { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 7px; }
.ins-screen i { aspect-ratio: 1; border-radius: 6px; background: rgba(255, 255, 255, .14); }
.ins-icon { display: block; line-height: 0; }
.ins-icon img { width: 100%; height: auto; border-radius: 6px; box-shadow: 0 0 0 2px var(--esn-cyan), 0 4px 12px rgba(0, 0, 0, .35); animation: ins-pop .7s cubic-bezier(.2, .9, .3, 1.3) .4s both; }
@keyframes ins-pop { from { opacity: 0; transform: scale(.3); } to { opacity: 1; transform: none; } }
.ins-sky { position: absolute; right: 0; bottom: -4px; width: min(100%, 560px); color: #fff; opacity: .12; pointer-events: none; }
.ins-qr-row { display: flex; align-items: center; gap: 14px; margin: 0 0 12px; }
.ins-qr { flex: 0 0 auto; padding: 8px; border-radius: var(--r-md); background: #fff; line-height: 0; }
.ins-qr img, .ins-qr canvas { display: block; width: 132px; height: 132px; }
.ins-qr-row.no-qr .ins-qr, .ins-qr-row.no-qr .ins-if-qr, .ins-qr-row:not(.no-qr) .ins-if-noqr { display: none; }
.ins-steps-head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 10px; }
.ins-steps-head h3 { margin: 0; }
.ins-list { display: grid; gap: 8px; margin: 12px 0 0; padding: 0; list-style: none; counter-reset: ins; }
.ins-step { counter-increment: ins; display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: 12px; padding: 10px 12px; border: 1px solid var(--border); border-radius: var(--r-md); background: var(--bg); }
.ins-num { display: inline-grid; place-items: center; width: 28px; height: 28px; border-radius: 50%; background: var(--esn-cyan); color: var(--on-bright); font-size: .85rem; font-weight: 900; }
.ins-num::before { content: counter(ins); }
.ins-step-text { display: flex; flex-direction: column; gap: 2px; font-size: .9rem; line-height: 1.4; }
.ins-step-text span { color: var(--muted); font-size: .85rem; }
.ins-key { display: inline-flex; align-items: center; justify-content: center; justify-self: end; min-width: 40px; height: 40px; padding: 0 10px; border: 1px solid var(--border); border-radius: 12px; background: var(--card); color: var(--ink); box-shadow: var(--shadow); }
.ins-pill { display: inline-flex; align-items: center; gap: 4px; font-size: .8rem; font-weight: 700; white-space: nowrap; }
.ins-note { display: flex; align-items: flex-start; gap: 6px; margin: 10px 0 0; color: var(--muted); font-size: .85rem; line-height: 1.45; }
.ins-notif { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: 14px; }
.ins-notif h3 { margin: 0 0 2px; }
.ins-notif .form-hint { margin: 0; }
.ins-notif-ico { display: grid; place-items: center; width: 44px; height: 44px; border-radius: 12px; background: rgba(0, 174, 239, .14); color: var(--accent-text); }
.ins-perks { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; margin: 0 0 18px; }
.ins-perk { display: flex; flex-direction: column; gap: 4px; padding: 14px; border: 1px solid var(--border); border-radius: var(--r-md); background: var(--card); }
.ins-perk strong { font-size: .95rem; }
.ins-perk > span:last-child { color: var(--muted); font-size: .8rem; line-height: 1.4; }
.ins-perk-ico { display: grid; place-items: center; width: 36px; height: 36px; margin-bottom: 4px; border-radius: 10px; color: var(--on-bright); }
.ins-perk-ico.p1 { background: var(--esn-cyan); }
.ins-perk-ico.p2 { background: var(--magenta-deep); color: #fff; }
.ins-perk-ico.p3 { background: var(--esn-green); }
.ins-perk-ico.p4 { background: var(--esn-orange); }
.ins-help { margin: 0 0 10px; }
.ins-q { margin: 0 0 8px; border: 1px solid var(--border); border-radius: var(--r-md); background: var(--card); }
.ins-q summary { padding: 12px 14px; cursor: pointer; font-size: .9rem; font-weight: 700; }
.ins-q p { margin: 0; padding: 0 14px 12px; color: var(--muted); font-size: .85rem; line-height: 1.5; }
.ins-q .btn { margin: 0 14px 12px; }
@media (min-width: 760px) {
  .ins-hero { padding: 26px 28px 28px; gap: 28px; }
  #app h2.ins-title { font-size: 1.7rem; }
  .ins-lede { font-size: .95rem; }
  .ins-phone { width: 124px; height: 224px; padding: 26px 12px 12px; border-radius: 24px; }
  .ins-screen { gap: 10px; }
  .ins-perks { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
@media (max-width: 480px) {
  .ins-key { min-width: 36px; height: 36px; padding: 0 8px; }
  .ins-key.wide { grid-column: 2; justify-self: start; }
  .ins-pill-t { display: none; }
  .ins-steps .chip { padding-left: 12px; padding-right: 12px; }
  .ins-notif { grid-template-columns: auto minmax(0, 1fr); }
  .ins-notif .btn { grid-column: 1 / -1; justify-self: start; }
  .ins-qr-row { flex-direction: column; align-items: flex-start; }
}

/* ---------- v0.126 ---------- */
/* Visual icon picker (event form inline + tag-manager dialog) */
.icon-pick {
  display: flex; flex-wrap: wrap; gap: 6px;
  max-height: 132px; overflow-y: auto;
  padding: 8px; border: 1px solid var(--border); border-radius: 10px;
  background: var(--card);
}
.icon-opt {
  width: 38px; height: 38px; border-radius: 9px;
  border: 1px solid var(--border); background: var(--card); color: var(--ink);
  display: inline-flex; align-items: center; justify-content: center;
  cursor: pointer; padding: 0;
}
.icon-opt .material-symbols-rounded { font-size: 1.3rem; }
.icon-opt:hover { background: var(--hover); }
.icon-opt.sel { border-color: var(--esn-cyan); background: var(--esn-cyan); color: var(--on-bright); }
.icon-opt.icon-auto { width: auto; padding: 0 12px; font-weight: 800; font-size: .8rem; }

/* ---------- v0.127: passport rework ---------- */
/* Breathing room above the passport cover */
.passport { padding-top: 6px; max-width: var(--w-wide); margin-left: auto; margin-right: auto; }
/* Avatar + level ring in the cover (photo inside a conic XP ring) */
/* The RESTING value is the real one, and the animation sweeps up to it from
     zero. Done the other way round (start at 0, animate to the value) the ring
     renders permanently empty for anyone with reduced motion on, because the
     global reset above kills the animation that was the only thing setting it. */
.pp-idring {
  width: 66px; height: 66px; border-radius: 50%; flex: 0 0 66px;
  padding: 4px; position: relative;
  display: flex; align-items: center; justify-content: center; --pp-ring: var(--pp-deg, 0deg); background: conic-gradient(var(--pp-c, var(--esn-cyan)) var(--pp-ring), rgba(255, 255, 255, .18) 0deg); animation: pp-ring-fill 1.05s .2s cubic-bezier(.22, 1, .36, 1) both;
}
.pp-idring-inner {
  width: 100%; height: 100%; border-radius: 50%; overflow: hidden;
  background: #20235f; display: flex; align-items: center; justify-content: center;
  border: 2px solid rgba(255,255,255,.12);
}
.pp-idring-inner img { width: 100%; height: 100%; object-fit: cover; }
.pp-idring-mono { font-weight: 900; font-size: 1.45rem; color: #fff; }
/* The level number lands after the ring reaches it. */
.pp-idring-lvl {
  position: absolute; bottom: -2px; right: -2px; min-width: 22px; height: 22px;
  padding: 0 5px; border-radius: 11px; border: 2px solid #232668;
  color: #fff; font-weight: 900; font-size: .8rem;
  display: flex; align-items: center; justify-content: center; animation: pp-pop .5s .95s cubic-bezier(.34, 1.56, .64, 1) both;
}
/* Visa cards: tiered, iconed, tappable, with a progress bar */
.visa-grid2 {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 12px; margin-bottom: 6px;
}
.visa-card {
  position: relative; text-align: left; cursor: pointer;
  background: var(--card); border: 1px solid var(--border); border-radius: var(--r-md);
  padding: 14px 14px 12px; display: flex; flex-direction: column; gap: 5px;
  color: var(--ink); font: inherit;
  border-top: 3px solid var(--tier);
  transition: transform var(--t-fast) ease, box-shadow var(--t-fast) ease;
}
.visa-card:hover { transform: translateY(-2px); box-shadow: var(--shadow-lg); }
.visa-card:not(.got) { opacity: .72; }
.visa-card.top { box-shadow: 0 0 0 1px var(--tier) inset; }
.visa-rank { position: absolute; top: 8px; right: 10px; font-size: 1.15rem; }
.visa-ic { position: relative; width: 40px; height: 40px; display: inline-flex; align-items: center; justify-content: center;
  border-radius: 11px; background: color-mix(in srgb, var(--visa) 16%, transparent); color: var(--visa); }
.visa-ic .material-symbols-rounded { font-size: 1.45rem; }
.visa-card:not(.got) .visa-ic { background: var(--hover); color: var(--muted); }
.visa-count {
  position: absolute; top: -6px; right: -6px; min-width: 18px; height: 18px; padding: 0 4px;
  border-radius: 9px; background: var(--tier); color: #fff; font-size: .7rem; font-weight: 900;
  display: flex; align-items: center; justify-content: center; border: 2px solid var(--card);
}
.visa-name { font-size: .9rem; font-weight: 800; margin-top: 2px; }
.visa-tier { font-size: .75rem; font-weight: 700; color: var(--tier); text-transform: uppercase; letter-spacing: .03em; }
.visa-card:not(.got) .visa-tier { color: var(--muted); }
.visa-bar { display: block; height: 5px; border-radius: 3px; background: rgba(128,128,160,.24); overflow: hidden; margin-top: 3px; }
.visa-bar i { display: block; height: 100%; border-radius: 3px; background: var(--tier); width: 100%; transform: translateX(calc(var(--p, 0%) - 100%)); transition: transform .4s ease; }
.visa-next { font-size: .75rem; color: var(--muted); }
/* Merged ESN Volunteer block */
.pp-vol {
  background: var(--card); border: 1px solid var(--border); border-radius: var(--r-lg);
  padding: 16px; margin-bottom: 14px;
}
.pp-vol-head { display: flex; justify-content: space-between; align-items: baseline; flex-wrap: wrap; gap: 6px; margin-bottom: 12px; }
.pp-vol-role { font-weight: 800; }
.pp-vol-count { font-size: .8rem; color: var(--muted); }
/* The level ring fills round rather than appearing full. A conic-gradient
   angle is not animatable on its own, so it goes through a registered custom
   property; browsers without @property simply show the final angle. */
@property --pp-ring {
  syntax: "<angle>";
  inherits: false;
  initial-value: 0deg;
}  /* 1.7.0: ESN Passport motion */
.pp-vol .kpi-grid.four { grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); }  /* 1.29.0: passport 3 */

/* ---------- v0.129: contact & inbox threads ---------- */
.ct-bubble {
  border-radius: var(--r-md); padding: 8px 12px; margin: 6px 0; max-width: 92%;
  background: var(--hover); border: 1px solid var(--border);
}
.ct-bubble.mine { margin-left: auto; background: color-mix(in srgb, var(--esn-cyan) 12%, var(--card)); }
.ct-bubble small { color: var(--muted); font-size: .75rem; }
.ct-bubble p { font-size: .9rem; }

/* ---------- Scan page: today's events + mode cards (v0.131) ---------- */
/* Scan page: today's events + mode cards */
.scan-now { margin: 6px 0 18px; }
.scan-ev-ico {
  width: 40px; height: 40px; border-radius: 11px; flex: 0 0 40px;
  display: flex; align-items: center; justify-content: center;
  background: color-mix(in srgb, var(--esn-cyan) 15%, transparent); color: var(--esn-cyan);
}
.scan-ev-bar { flex-basis: 100%; height: 6px; border-radius: 3px; background: var(--hover); overflow: hidden; }
.scan-ev-bar i { display: block; height: 100%; border-radius: 3px; background: var(--esn-green); width: 100%; transform: translateX(calc(var(--p, 0%) - 100%)); transition: transform .4s ease; }
@media (max-width: 560px) {
  .scan-modes { grid-template-columns: minmax(0, 1fr); }
}

/* ---------- Admin dashboard deltas + mini chart (v0.131) ---------- */
/* Admin dashboard: month-delta chips + weekly mini chart */
.stat-delta { display: block; font-size: .7rem; font-weight: 800; margin-top: 3px; }
.stat-delta.up { color: var(--green-text); }
.stat-delta.down { color: var(--esn-magenta); }
.mini-chart-card {
  background: var(--card); border: 1px solid var(--border); border-radius: var(--r-md);
  padding: 14px 16px 8px; margin: 0 0 18px;
}
.mini-chart-card svg { width: 100%; height: 96px; display: block; }
.mini-chart-card .bar { fill: #0071a0; }
html[data-theme="dark"] .mini-chart-card .bar { fill: var(--esn-cyan); }
.mini-chart-card .bar-label { font: 700 11px Lato, Arial, sans-serif; fill: var(--muted); }
.mini-chart-card .bar:hover { opacity: .8; }
details.mini-chart-card > summary { cursor: pointer; list-style: none; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }  /* v0.137: Admin dashboard */
details.mini-chart-card > summary::-webkit-details-marker { display: none; }
details.mini-chart-card > summary::after { content: "expand_more"; font-family: "Material Symbols Rounded"; margin-left: auto; opacity: .6; }
details.mini-chart-card[open] > summary::after { content: "expand_less"; }
html[data-theme="dark"] .stat-delta.down { color: #ff8a8a; }  /* 1.29.4: one system */

/* ---------- Ticket cards on /my-tickets (v0.137) ---------- */
.tk-list { display: flex; flex-direction: column; gap: 10px; margin-bottom: 8px; }
/* My tickets (1.29.3): every row has the same shape on every screen:
   icon, three short lines and a small chip on the left, the buttons on the
   right, all the same size. */
.tk-item {
  display: flex; align-items: center;
  background: var(--card); border: 1px solid var(--border);
  box-shadow: var(--shadow); border-left: 4px solid var(--accent, var(--esn-cyan)); padding: 12px 14px; gap: 12px; flex-wrap: nowrap; border-radius: var(--radius);
}
.tk-item.past { opacity: .78; }
.tk-item[data-evlink]:hover { border-color: var(--accent, var(--esn-cyan)); }
.tk-ico {
  flex: 0 0 42px; width: 42px; height: 42px; border-radius: 50%;
  display: grid; place-items: center; color: #fff; background: var(--accent, var(--esn-cyan));
  background: color-mix(in srgb, var(--accent, var(--esn-cyan)) 75%, #000);  /* 1.55.0: the icon stands out (3:1 and up) */
}
.tk-ico .material-symbols-rounded { font-size: 20px; }
.tk-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.tk-main strong { line-height: 1.25; font-size: 1rem; }
.tk-main small { color: var(--muted); display: flex; align-items: center; gap: 4px; flex-wrap: wrap; font-size: .8rem; }
.tk-main small .material-symbols-rounded { font-size: 14px; }
.tk-right { display: flex; flex: 0 0 auto; flex-direction: column; align-items: stretch; gap: 6px; width: auto; padding: 0; min-width: 92px; }
.tk-actions { display: flex; gap: 6px; flex-wrap: wrap; justify-content: flex-end; }
.tk-stats .stat-card { min-height: 70px; padding: 12px; }
.tk-in { display: flex; align-items: center; gap: 12px; width: 100%; max-width: 360px; padding: 12px 14px; border-radius: var(--r-md); background: rgba(122, 193, 67, .14); border: 1px solid rgba(122, 193, 67, .45); }  /* v0.137: Ticket page polish */
.tk-in-ico .material-symbols-rounded { font-size: 32px; color: var(--esn-green); }
.tk-in strong { font-size: 1.05rem; color: var(--green-text); }
.tk-opt { flex-direction: column; text-align: left; width: 100%; align-items: flex-start; justify-content: flex-start; }
.tk-opt small { font-weight: 400; font-size: .75rem; color: var(--muted); }
.tk-status {
  display: inline-flex; align-items: center; gap: 4px; align-self: flex-start; margin-top: 2px;
  padding: 2px 8px; border-radius: 999px; font-size: .7rem; font-weight: 800; letter-spacing: .2px;
}  /* 1.29.3: event page polish */
.tk-status .material-symbols-rounded { font-size: 14px; }
.tk-status.ok { background: color-mix(in srgb, var(--esn-green) 18%, transparent); color: var(--green-text); }
.tk-status.wait { background: color-mix(in srgb, var(--esn-orange) 18%, transparent); color: var(--orange-text); }
.tk-status.off { background: var(--surface2); color: var(--muted); }
.tk-right .btn { justify-content: center; padding-left: 10px; padding-right: 10px; }
.tk-rate { border-color: transparent; color: var(--orange-text); }
.tk-quiet { color: var(--muted); border-color: transparent; font-weight: 600; }
.tk-quiet:hover { color: var(--esn-magenta); }
.tk-item.tk-mark .tk-ico { background: color-mix(in srgb, var(--accent, var(--esn-cyan)) 22%, transparent); color: var(--accent, var(--esn-cyan)); }
.tk-list + details, #arch-details { margin-top: 18px; }
#arch-details > summary { list-style: none; }
#arch-details > summary::-webkit-details-marker { display: none; }
.arch-sum { cursor: pointer; display: inline-flex; align-items: center; gap: 6px; }
.arch-n { font-size: .75rem; font-weight: 800; color: var(--muted); background: var(--surface2); border-radius: 999px; padding: 1px 8px; }
.arch-chev { display: inline-flex; color: var(--muted); transition: transform .15s; }
#arch-details[open] .arch-chev { transform: rotate(180deg); }
html[data-theme="dark"] .tk-item.tk-mark .tk-ico {
  color: color-mix(in srgb, var(--accent, var(--esn-cyan)) 55%, #fff);
  background: color-mix(in srgb, var(--accent, var(--esn-cyan)) 30%, transparent);
}  /* 1.29.4: sweep */
.tk-rate.done { color: var(--orange-text); }  /* 1.29.4: one system */
/* My tickets stats: three tiles fit one row on a phone */
.tk-stats { grid-template-columns: repeat(auto-fit, minmax(96px, 1fr)) !important; }  /* 1.29.4: colour follow-ups */
@media (max-width: 560px) {
  .tk-right { justify-content: space-between; flex-direction: column; align-items: stretch; width: auto; padding-left: 0; }
  .tk-item { flex-wrap: nowrap; }  /* 1.29.3: event page polish */
  .tk-main { flex-basis: auto; }
  .tk-ico { flex-basis: 38px; width: 38px; height: 38px; }
  .tk-ico .material-symbols-rounded { font-size: 20px; }
}

/* ---------- Ticket page polish (v0.137) ---------- */
/* "Ticket options" — cancel/refund/transfer tucked behind a collapsed row */
.ticket-more summary { cursor: pointer; font-size: .85rem; font-weight: 700; color: var(--muted); list-style: none; }
.ticket-more summary::-webkit-details-marker { display: none; }
.ticket-more summary::after { content: "▾"; margin-left: 6px; font-size: .75rem; }
.ticket-more[open] summary::after { content: "▴"; }
.ticket-kicker { display: inline-flex; align-items: center; gap: 4px; font-size: .8rem; font-weight: 700; letter-spacing: .4px; text-transform: uppercase; opacity: .85; margin-bottom: 4px; }
.ticket-when { display: flex; align-items: center; justify-content: center; gap: 4px; flex-wrap: wrap; }
.ticket-when .material-symbols-rounded { font-size: 16px; }
.ticket-facts { list-style: none; margin: 0; padding: 0; width: 100%; max-width: 360px; display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.ticket-facts li { display: flex; flex-direction: column; gap: 2px; padding: 8px 10px; border: 1px solid var(--border); border-radius: 10px; background: var(--bg); }
.ticket-facts li span { font-size: .75rem; color: var(--muted); display: inline-flex; align-items: center; gap: 3px; }
.ticket-facts li span .material-symbols-rounded { font-size: 14px; }
.ticket-facts li strong { font-size: .9rem; overflow-wrap: anywhere; }
.ticket-facts .mono { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: .8rem; }
.ticket-transfer { width: 100%; max-width: 360px; padding: 12px 14px; border-radius: var(--r-md); background: var(--bg); border: 1px dashed var(--border); text-align: center; }
.ticket-transfer p { margin: 0 0 8px; }
.ticket-btns { display: flex; gap: 8px; flex-wrap: wrap; justify-content: center; margin: 4px 0 0; }
.ticket-more { width: 100%; max-width: 360px; }

/* ---------- Product page (v0.137) ---------- */
.product-page { max-width: var(--w-wide); margin: 0 auto; }
.product-grid { display: grid; grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr); gap: 22px; align-items: start; }
.product-media { border-radius: var(--radius); overflow: hidden; border: 1px solid var(--border); background: var(--card); aspect-ratio: 1 / 1; display: grid; place-items: center; }
.product-media img { width: 100%; height: 100%; object-fit: cover; display: block; }
.product-noimg .material-symbols-rounded { font-size: 72px; color: var(--muted); }
.product-info { background: var(--card); border: 1px solid var(--border); border-radius: var(--radius); box-shadow: var(--shadow); padding: 20px; display: flex; flex-direction: column; gap: 14px; border-top: 4px solid var(--accent, var(--esn-cyan)); }
.product-info h1 { margin: 0; font-size: 1.45rem; font-weight: 900; line-height: 1.2; }
.product-price { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.product-price .price-tag { font-size: 1.7rem; }
.product-field { display: flex; flex-direction: column; gap: 6px; }
.product-label { font-size: .8rem; font-weight: 700; color: var(--muted); text-transform: uppercase; letter-spacing: .4px; }
.chip-row .chip[disabled] { opacity: .45; text-decoration: line-through; cursor: not-allowed; }
.qty-step { display: inline-flex; align-items: center; border: 1px solid var(--border); border-radius: 999px; overflow: hidden; width: max-content; }
.qty-step input { width: 52px; text-align: center; border: 0; background: transparent; font-weight: 800; font-size: 1rem; padding: 8px 0; -moz-appearance: textfield; }
.qty-step input::-webkit-outer-spin-button, .qty-step input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.qty-btn { border: 0; background: var(--bg); width: 40px; height: 38px; display: grid; place-items: center; cursor: pointer; color: var(--ink); }
.qty-btn:hover { background: var(--border); }
.product-cta { font-size: 1.05rem; padding: 14px; }
.product-steps { list-style: none; margin: 4px 0 0; padding: 12px 0 0; border-top: 1px solid var(--border); display: flex; flex-direction: column; gap: 8px; font-size: .85rem; color: var(--muted); }
.product-steps li { display: flex; align-items: center; gap: 10px; }
.product-steps li > span + span { flex: 1; min-width: 0; } /* 1.70.1: the text in one box, a link no longer makes its own column */
.product-steps li > span:first-child { width: 30px; height: 30px; border-radius: 50%; background: var(--bg); border: 1px solid var(--border); display: grid; place-items: center; color: var(--accent-text); flex: 0 0 30px; }
html[data-theme="dark"] .product-steps li > span:first-child { color: var(--esn-cyan); }
.product-desc { margin-top: 22px; background: var(--card); border: 1px solid var(--border); border-radius: var(--radius); padding: 18px 20px; }
.chip-row { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 6px; }  /* v1.1.0: ESNcard application */
@media (max-width: 760px) {
  .product-grid { grid-template-columns: minmax(0, 1fr); gap: 14px; }
  .product-media { aspect-ratio: 4 / 3; }
}

/* ---------- The team space (1.67.0): /crew ---------- */
.crew-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 14px; margin-bottom: 18px; }
.crew-ask { border-color: var(--esn-orange); box-shadow: inset 4px 0 0 var(--esn-orange); margin-bottom: 14px; }
.crew-vom { border-color: var(--esn-magenta); margin-bottom: 14px; background: linear-gradient(90deg, rgba(236, 0, 140, .06), transparent); }
.crew-vom-head { display: flex; gap: 14px; align-items: center; }
.crew-vom-head strong { font-size: 1.15rem; display: block; }
.crew-kicker { display: inline-flex; align-items: center; gap: 4px; font-size: .75rem; text-transform: uppercase; letter-spacing: .4px; color: var(--muted); font-weight: 700; margin: 0 0 4px; }
.crew-stats { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px; margin-top: 10px; }
.crew-stats div { text-align: center; background: var(--surface2); border-radius: var(--r-md); padding: 8px 4px; }
.crew-stats b { display: block; font-size: 1.3rem; line-height: 1.1; }
.crew-stats small { color: var(--muted); font-size: .75rem; }
.crew-next-row { display: flex; justify-content: space-between; gap: 10px; flex-wrap: wrap; padding: 10px 0; border-top: 1px solid var(--border); }
.crew-next-row:first-of-type { border-top: 0; padding-top: 0; }
.crew-next-acts { display: flex; gap: 6px; flex-wrap: wrap; align-items: flex-start; }
.crew-mates { display: flex; align-items: center; gap: 4px; margin-top: 6px; flex-wrap: wrap; }
.crew-mates small { color: var(--muted); margin-left: 4px; }
.crew-open { margin-bottom: 18px; }
.crew-faces { display: flex; flex-wrap: wrap; gap: 8px 10px; }
.crew-face { display: inline-flex; flex-direction: column; align-items: center; gap: 3px; width: 56px; }
.crew-face small { font-size: .75rem; color: var(--muted); max-width: 56px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.crew-thank-ev { margin-bottom: 10px; }
.crew-thank { font-family: inherit; background: none; border: 1px solid var(--border); border-radius: var(--r-md); padding: 6px; display: inline-flex; flex-direction: column; align-items: center; gap: 3px; width: 64px; cursor: pointer; color: var(--ink); }
.crew-thank small { font-size: .75rem; display: inline-flex; align-items: center; gap: 2px; max-width: 56px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.crew-thank:hover { border-color: var(--esn-magenta); }
.crew-thank.done { border-color: var(--esn-green); color: var(--green-text); cursor: default; }
.crew-thanks { list-style: none; margin: 10px 0 0; padding: 0; display: flex; flex-direction: column; gap: 6px; font-size: .9rem; }
.crew-thanks li { display: flex; gap: 6px; align-items: flex-start; }
.crew-thanks .material-symbols-rounded { color: var(--esn-magenta); flex-shrink: 0; margin-top: 2px; }
.crew-news { margin-bottom: 18px; }
.crew-links { display: grid; grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); gap: 10px; margin-bottom: 18px; }
.crew-links a, .crew-links button { font-family: inherit; font-size: .85rem; font-weight: 700; display: flex; flex-direction: column; align-items: center; gap: 6px; padding: 14px 8px; border: 1px solid var(--border); border-radius: var(--r-md); background: var(--card); color: var(--ink); text-decoration: none; cursor: pointer; }
.crew-links .material-symbols-rounded { color: var(--esn-cyan); }
.crew-links a:hover, .crew-links button:hover { border-color: var(--esn-cyan); }
@media (max-width: 640px) {
  .crew-grid { grid-template-columns: minmax(0, 1fr); }
  .crew-stats b { font-size: 1.15rem; }
}

/* ---------- People on the Join page and in Crew (1.67.2) ---------- */
.join-faces { margin: 18px 0 6px; }
.join-faces-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 12px; }
.join-face { margin: 0; display: flex; flex-direction: column; align-items: center; text-align: center; gap: 8px; padding: 14px 10px; border: 1px solid var(--border); border-radius: var(--r-md); background: var(--card); }
.join-face figcaption { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.join-face figcaption span { font-size: .85rem; color: var(--muted); font-style: italic; overflow-wrap: anywhere; }
.join-gallery { display: flex; gap: 8px; overflow-x: auto; scrollbar-width: none; margin: 14px -16px 0; padding: 0 16px; scroll-snap-type: x mandatory; }
.join-gallery::-webkit-scrollbar { display: none; }
.join-gallery img { height: 150px; width: auto; max-width: 70vw; border-radius: var(--r-md); object-fit: cover; flex: none; scroll-snap-align: start; }
.join-numbers { display: flex; flex-wrap: wrap; gap: 6px 18px; color: var(--muted); font-size: .9rem; margin: 14px 0 4px; }
.join-numbers b { color: var(--ink); font-size: 1.05rem; }
.join-type.has-photo { padding: 0; overflow: hidden; align-items: stretch; }
.join-type-photo { width: 96px; min-height: 84px; object-fit: cover; flex-shrink: 0; }
.join-type.has-photo > div { padding: 12px 14px; }
.join-pics { margin: 0 0 18px; }
.join-pics-row { display: flex; gap: 8px; overflow-x: auto; scrollbar-width: none; margin: 0 -16px; padding: 0 16px; }
.join-pics-row::-webkit-scrollbar { display: none; }
.join-pics-row a { flex: none; }
.join-pics-row img { height: 110px; width: 150px; object-fit: cover; border-radius: var(--r-md); display: block; }
.join-mgmt { display: inline-flex; margin-right: 6px; vertical-align: middle; }
.join-mgmt .av { margin-left: -6px; border: 2px solid var(--card); }
.join-mgmt .av:first-child { margin-left: 0; }
.join-leads { display: flex; flex-wrap: wrap; gap: 6px 14px; margin-top: 8px; }
.join-lead { display: inline-flex; align-items: center; gap: 5px; color: var(--muted); font-size: .8rem; opacity: .7; }
.join-lead.on { opacity: 1; color: var(--ink); }
.crew-sentence { margin: 10px 0 0; font-size: .95rem; line-height: 1.5; }
.crew-sentence b { font-size: 1.05rem; }
.crew-buddy { display: flex; align-items: center; gap: 8px; margin: 10px 0 0; font-size: .9rem; }
.crew-line { margin: 10px 0 0; font-size: .9rem; color: var(--muted); }
.crew-face .crew-face-sub { color: var(--magenta-text); font-weight: 700; }
.crew-newcomers { display: flex; flex-direction: column; gap: 8px; }
.crew-newcomer { display: flex; align-items: center; gap: 10px; }
.crew-newcomer small { color: var(--muted); font-style: italic; }
.al-faces { display: grid; grid-template-columns: repeat(auto-fill, minmax(84px, 1fr)); gap: 14px 10px; margin-top: 10px; }  /* 1.78.7: the Alumni tab for alumni */
.al-face { display: flex; flex-direction: column; align-items: center; gap: 6px; text-align: center; font-size: .8rem; line-height: 1.25; }
.al-card .tcard-top { align-items: flex-start; }  /* 1.78.7: the directory card: the actions are icons beside the name */
.al-acts { display: flex; flex: none; gap: 4px; margin-left: auto; }
.al-card .tcard-id { flex: 1 1 auto; }
.al-explainer { padding: 12px 16px; }
.al-guide { margin: 0 0 14px; border-top: 3px solid var(--esn-orange); }  /* 1.78.8: organising an alumni event, step by step */
.al-steps { list-style: none; margin: 10px 0 0; padding: 0; display: grid; gap: 12px; }
.al-step { display: flex; align-items: flex-start; gap: 12px; }
.al-step-n { flex: none; display: grid; place-items: center; width: 28px; height: 28px; border-radius: 50%; background: var(--surface2); color: var(--ink); font-weight: 900; font-size: .85rem; }
.al-step.done .al-step-n { background: var(--esn-green); color: var(--on-bright); }
.al-step.done > div > strong { color: var(--muted); }
@media (min-width: 900px) { .al-steps { grid-template-columns: repeat(5, minmax(0, 1fr)); } .al-step { flex-direction: column; gap: 8px; } }
/* 1.78.8: Team tabs tidied: one line instead of four tiles on Shifts, the occasional forms folded */
.shift-tally { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 14px; margin: 0 0 14px; font-size: .85rem; color: var(--muted); }
.shift-tally b { color: var(--ink); font-size: 1.05rem; font-weight: 900; margin-right: 3px; }
.shift-tally a { display: inline-flex; align-items: center; gap: 4px; margin-left: auto; font-weight: 700; }
/* 1.78.15: on a phone "Your season" is its icon (the link keeps its name), so three numbers stay on one line; a fourth wraps */
@media (max-width: 480px) { .shift-tally { gap: 6px 10px; } .shift-tally a { padding: 6px; margin: -6px -6px -6px auto; } .shift-tally .tally-more { display: none; } }
.al-fold > summary, .roles-fold > summary { cursor: pointer; display: flex; align-items: center; gap: 6px; font-weight: 700; }
.al-fold[open] > summary { margin-bottom: 8px; }
.rb-new { margin: 6px 0 18px; }
.rb-new > summary { list-style: none; width: fit-content; }
.rb-new > summary::-webkit-details-marker { display: none; }
.rb-new[open] > summary { display: none; }  /* 1.78.7: a folded line, not a tall empty card */
.al-explainer > summary { cursor: pointer; font-weight: 700; display: flex; align-items: center; gap: 6px; }
.al-explainer ol { margin: 10px 0 0; padding-left: 20px; display: flex; flex-direction: column; gap: 8px; font-size: .9rem; line-height: 1.5; }
.al-explainer ol a { text-decoration: underline; } /* 1.78.11: a link in running text is not told apart by colour alone (axe link-in-text-block) */
/* ---- 1.78.11: the alumni directory (alumni-page.js renderDirectory): a toolbar, quick filters with counts, a list or cards, groups.
   The list is .al-rows: .al-list is the Add to the directory button's class. ---- */
.al-tools input[type="search"] { flex: 1 1 260px; max-width: none; }
.al-viewsw { display: inline-flex; gap: 2px; padding: 2px; border: 1px solid var(--border); border-radius: var(--r-sm); background: var(--card); }
.al-viewsw .btn { border-color: transparent; min-height: 30px; }
.al-viewsw .btn[aria-pressed="true"] { background: var(--surface2); color: var(--ink); }
.al-tools .fsel { flex: 1 1 150px; }
.fsel .combo { flex: 1 1 auto; min-width: 0; }  /* 1.78.11: a long list inside a labelled box (the year): the box draws the border */
.fsel .combo-in { border: 0; background: transparent; box-shadow: none; height: 34px; padding: 0 8px 0 2px; font-size: .85rem; }
.al-quick { display: flex; flex-wrap: wrap; gap: 6px; }
.al-quick .chip { flex: none; padding: 6px 12px; font-size: .8rem; }
.al-quick .chip b { margin-left: 2px; }
.al-count-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.al-rows { list-style: none; margin: 0; padding: 0; background: var(--card); border: 1px solid var(--border); border-radius: var(--r-md); }
.al-row { display: grid; grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: "who acts" "yrs yrs" "state state"; gap: 6px 10px; align-items: center; padding: 10px 12px; border-top: 1px solid var(--border); min-width: 0; }
.al-row:first-child { border-top: 0; }
.al-row.is-editing { display: block; }
.al-row-who { grid-area: who; display: flex; align-items: center; gap: 10px; min-width: 0; }
.al-row-who strong { font-size: .95rem; line-height: 1.25; overflow-wrap: anywhere; }
.al-row-who small { font-size: .75rem; overflow-wrap: anywhere; }
.al-row-yrs { grid-area: yrs; font-size: .85rem; line-height: 1.4; min-width: 0; overflow-wrap: anywhere; }
.al-row-yrs b { color: var(--magenta-text); }
.al-row-state { grid-area: state; display: flex; flex-wrap: wrap; gap: 5px; }
.al-row .al-acts { grid-area: acts; justify-content: flex-end; }
.al-row .al-list-add, .al-row .al-hist-box { grid-column: 1 / -1; }
.al-list-head { display: none; }
.al-sort-h { display: inline-flex; align-items: center; gap: 2px; padding: 0; border: 0; background: none; font: inherit; color: inherit; text-transform: inherit; letter-spacing: inherit; cursor: pointer; }
.al-sort-h[aria-pressed="true"] { color: var(--ink); }
.al-group { margin: 0 0 12px; }
.al-group > summary { cursor: pointer; display: flex; align-items: baseline; gap: 8px; padding: 6px 2px; font-size: .95rem; }
.al-group > .al-rows, .al-group > .tgrid { margin-top: 4px; }
@media (min-width: 900px) {
  .al-row { grid-template-columns: minmax(220px, 1.3fr) minmax(0, 1.4fr) minmax(0, 1fr) 124px; grid-template-areas: "who yrs state acts"; }
  .al-list-head { display: grid; grid-template-columns: minmax(220px, 1.3fr) minmax(0, 1.4fr) minmax(0, 1fr) 124px; gap: 6px 10px; padding: 0 13px 6px; font-size: .75rem; font-weight: 700; text-transform: uppercase; letter-spacing: .5px; color: var(--muted); }
  .al-list-head > :first-child { padding-left: 40px; }  /* over the name, past the avatar */
}

/* ---- 1.78.7: the Team hub, redesigned (crew-page.js): a hero, quick actions, chips, three columns on a laptop ---- */
.th-hero { position: relative; display: flex; min-height: 190px; margin: 0 0 14px; border-radius: var(--r-lg); overflow: hidden; color: #fff; background: linear-gradient(135deg, var(--esn-dark) 0%, color-mix(in srgb, var(--th-accent, var(--esn-cyan)) 55%, var(--esn-dark)) 100%); box-shadow: var(--shadow); }
.th-hero-img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.th-hero::after { content: ""; position: absolute; inset: 0; background: linear-gradient(180deg, rgba(18, 20, 42, .5) 0%, rgba(18, 20, 42, .9) 62%); }
.th-hero-quiet { min-height: 0; }
.th-hero-body { position: relative; z-index: 1; display: flex; flex-direction: column; justify-content: flex-end; gap: 6px; width: 100%; padding: 22px; }
.th-hero-kicker { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 6px; font-size: .8rem; font-weight: 700; color: #e4e6fb; }
.th-hero-kicker b { color: var(--cyan-on-dark); font-weight: 900; }
.th-hero h3 { margin: 0; font-size: 1.7rem; font-weight: 900; line-height: 1.15; color: #fff; display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.th-hero-meta { display: flex; align-items: center; gap: 10px; margin: 2px 0 0; font-size: .9rem; line-height: 1.35; color: #e4e6fb; }  /* 1.78.7: the event and its hours on two lines beside the badge */
.th-hero-meta .ev-ico { flex: none; display: inline-flex; margin: 0; }
.th-hero-meta > span { display: flex; flex-direction: column; min-width: 0; }
.th-hero-meta b { overflow: hidden; color: #fff; font-weight: 800; text-overflow: ellipsis; white-space: nowrap; }
.th-hero-note { display: flex; align-items: flex-start; gap: 6px; width: fit-content; max-width: 100%; margin: 2px 0 0; padding: 6px 10px; border-radius: var(--r-sm); background: rgba(255, 255, 255, .14); color: #fff; font-size: .85rem; line-height: 1.35; }  /* 1.78.7: the shift's note, out of the time line */
.th-hero-note .material-symbols-rounded { flex: none; margin-top: 1px; color: var(--cyan-on-dark); }
.th-hero-mates { margin: 2px 0 0; display: flex; flex-wrap: wrap; align-items: center; gap: 4px; font-size: .85rem; color: #e4e6fb; }
.th-hero-mates span { margin-left: 4px; }
.th-hero-acts { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 8px; }
.th-hero .btn.th-hero-main { background: #fff; color: #2E3192; border-color: #fff; }  /* beats html[data-theme=dark] a.btn */
.th-hero .btn-ghost { color: #fff; border-color: rgba(255, 255, 255, .6); }
.th-hero .btn-ghost:hover { background: rgba(255, 255, 255, .14); }
.th-hero .th-first { background: rgba(255, 255, 255, .16); border-color: rgba(255, 255, 255, .5); color: #fff; font-size: .75rem; }
.th-actions { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); gap: 4px; margin: 0 0 14px; }
.th-actions a, .th-actions button { display: flex; flex-direction: column; align-items: center; gap: 5px; padding: 4px 0; border: 1px solid transparent; border-radius: var(--r-md); background: none; color: var(--ink); font: inherit; font-size: .75rem; font-weight: 700; line-height: 1.2; text-align: center; text-decoration: none; cursor: pointer; }
.th-actions a:hover, .th-actions button:hover { border-color: var(--c); text-decoration: none; }
.th-ic { display: grid; place-items: center; width: 44px; height: 44px; border-radius: 50%; background: color-mix(in srgb, var(--c) 13%, var(--card)); color: var(--c); }
.th-chips { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 14px; }
.th-chip { display: inline-flex; align-items: center; gap: 8px; padding: 5px 14px 5px 5px; border: 1px solid color-mix(in srgb, var(--c) 40%, var(--border)); border-radius: 999px; background: var(--card); color: var(--ink); font-size: .85rem; font-weight: 700; text-decoration: none; }
.th-chip:hover { background: var(--hover); text-decoration: none; }
.th-chip b { display: inline-grid; place-items: center; min-width: 26px; height: 26px; padding: 0 6px; border-radius: 999px; background: var(--surface2); color: var(--c); font-weight: 900; }
.th-grid { display: grid; grid-template-columns: minmax(0, 1fr); grid-template-areas: "team" "me" "board"; gap: 14px; align-items: start; margin: 0 0 18px; }
.th-col { display: flex; flex-direction: column; gap: 14px; min-width: 0; }
.th-col-team { grid-area: team; }
.th-col-me { grid-area: me; }
.th-col-board { grid-area: board; }
.th-card { border-top: 3px solid var(--th-accent, var(--border)); }
.th-vom { display: flex; align-items: center; gap: 14px; background: linear-gradient(90deg, rgba(236, 0, 140, .07), transparent 70%), var(--card); }
.th-vom .av { width: 64px; height: 64px; font-size: 1.3rem; }
.th-vom strong { display: block; font-size: 1.15rem; }
.th-vom q { display: block; margin-top: 4px; font-size: 1.05rem; font-style: italic; line-height: 1.4; }
.th-faces .crew-kicker { margin-top: 12px; }
.th-faces .crew-faces { flex-wrap: nowrap; overflow-x: auto; overscroll-behavior-x: contain; scroll-snap-type: x proximity; scrollbar-width: none; padding: 2px 0 4px; }  /* 1.78.7: one row you swipe, not five rows of faces */
.th-faces .crew-faces::-webkit-scrollbar { display: none; }
.th-faces .crew-face { flex: none; scroll-snap-align: start; }
.th-faces .dash-title + .crew-kicker { margin-top: 4px; }
.th-pics .join-pics { margin: 0; }
.th-pics .join-pics-row { margin: 0; padding: 0; }
.th-pics .join-pics-row img { width: 200px; height: 140px; }
.th-feed { list-style: none; margin: 12px 0 0; padding: 12px 0 0; border-top: 1px solid var(--border); display: flex; flex-direction: column; gap: 10px; font-size: .9rem; }
.th-feed li { display: flex; align-items: flex-start; gap: 10px; }
.th-feed-avs { display: inline-flex; flex: none; padding-top: 1px; }
.th-feed-avs .av + .av { margin-left: -6px; box-shadow: 0 0 0 2px var(--card); }
.th-feed em { color: var(--muted); }
.th-season-top { display: flex; align-items: center; gap: 16px; margin-top: 10px; }
@property --th-p { syntax: "<number>"; inherits: false; initial-value: 0; }  /* 1.78.7: a registered number, so the ring can fill up on arrival */
.th-ring { flex: none; display: grid; place-items: center; width: 92px; height: 92px; border-radius: 50%; background: conic-gradient(var(--esn-green) calc(var(--th-p) * 1%), var(--surface2) 0); }
.th-ring > span { display: flex; flex-direction: column; align-items: center; justify-content: center; width: 72px; height: 72px; border-radius: 50%; background: var(--card); }
.th-ring b { font-size: 1.3rem; font-weight: 900; line-height: 1.1; }
.th-ring small { font-size: .75rem; color: var(--muted); }
.th-next-reward { display: flex; align-items: center; gap: 6px; margin: 8px 0 0; padding: 6px 10px; border-radius: var(--r-sm); background: color-mix(in srgb, var(--esn-orange) 10%, var(--card)); font-size: .85rem; }
.th-next-reward .material-symbols-rounded { color: var(--orange-text); }
.th-stat-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 12px; }
.th-stat-chips a, .th-stat-chips span { padding: 4px 10px; border-radius: 999px; background: var(--surface2); color: var(--ink); font-size: .8rem; text-decoration: none; }
.th-stat-chips a:hover { background: var(--hover); text-decoration: none; }
.th-news-row { margin: 8px 0 0; }
.th-team-evs { grid-template-columns: minmax(0, 1fr); margin: 10px 0 0; }
.th-oneline { display: flex; align-items: center; gap: 8px; margin: 0; padding: 12px 14px; border: 1px dashed var(--border); border-radius: var(--r-md); color: var(--muted); font-size: .9rem; }
.th-oneline .material-symbols-rounded { color: var(--cyan-text); }
html[data-theme="dark"] .th-chip, html[data-theme="dark"] .th-actions a, html[data-theme="dark"] .th-stat-chips a, html[data-theme="dark"] a.team-ev { color: var(--ink); }
/* 1.78.7: the hub arrives: the cards rise in one after the other, the picture settles, the season ring fills; once per visit (.th-enter), never with reduced motion */
@keyframes th-rise { from { opacity: 0; transform: translateY(12px); } }
@keyframes th-zoom { from { transform: scale(1.1); } }
@keyframes th-fill { from { --th-p: 0; } }
@media (prefers-reduced-motion: no-preference) {
  .th-enter .th-hero, .th-enter .th-actions > *, .th-enter .th-chips, .th-enter .th-col > * { animation: th-rise .5s cubic-bezier(.2, .7, .3, 1) both; }
  .th-enter .th-actions > :nth-child(1) { animation-delay: 60ms; }
  .th-enter .th-actions > :nth-child(2) { animation-delay: 95ms; }
  .th-enter .th-actions > :nth-child(3) { animation-delay: 130ms; }
  .th-enter .th-actions > :nth-child(4) { animation-delay: 165ms; }
  .th-enter .th-actions > :nth-child(5) { animation-delay: 200ms; }
  .th-enter .th-chips { animation-delay: 220ms; }
  .th-enter .th-col > :nth-child(1) { animation-delay: 260ms; }
  .th-enter .th-col > :nth-child(2) { animation-delay: 320ms; }
  .th-enter .th-col > :nth-child(n+3) { animation-delay: 380ms; }
  .th-enter .th-hero-img { animation: th-zoom 1.6s cubic-bezier(.2, .7, .3, 1) both; }
  .th-enter .th-ring { animation: th-fill 1.1s .45s cubic-bezier(.2, .7, .3, 1) both; }
  .th-ic { transition: transform .2s cubic-bezier(.2, .7, .3, 1.4), background .2s ease; }
  .th-actions a:active .th-ic, .th-actions button:active .th-ic { transform: scale(.88); }
  .th-chip { transition: transform .15s ease; }
  .th-chip:active { transform: scale(.97); }
}
@media (min-width: 821px) {
  .th-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); grid-template-areas: "me team" "board board"; }
  .th-actions { grid-auto-flow: row; grid-template-columns: repeat(auto-fit, minmax(110px, 1fr)); gap: 8px; }
  .th-actions a, .th-actions button { min-height: 80px; padding: 10px 4px; border-color: var(--border); background: var(--card); font-size: .8rem; }
  .th-hero { min-height: 220px; }
  .th-hero-body { padding: 28px; }
  .th-hero h3 { font-size: 2rem; }
}
@media (min-width: 1100px) {
  .th-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); grid-template-areas: "me team board"; }
}
.tc-types { display: flex; flex-direction: column; gap: 8px; }
.tc-type { display: grid; grid-template-columns: 56px minmax(0, 1fr) minmax(0, 2fr) 110px auto auto auto; gap: 8px; align-items: center; }
.tc-type img { width: 56px; height: 44px; object-fit: cover; border-radius: 8px; }
.tc-type .join-type-ic { width: 44px; height: 44px; }
.tc-type input { min-width: 0; }
.tc-hero { display: flex; gap: 12px; align-items: center; flex-wrap: wrap; }
.tc-hero-prev { width: 160px; height: 90px; border-radius: var(--r-md); background: var(--esn-dark) center / cover; flex-shrink: 0; }
.tc-gallery { display: flex; flex-wrap: wrap; gap: 8px; }
.tc-gal { position: relative; display: inline-block; }
.tc-gal img { width: 120px; height: 80px; object-fit: cover; border-radius: var(--r-md); display: block; }
.tc-gal .chip-x { position: absolute; top: 4px; right: 4px; background: var(--card); border-radius: 50%; }
.tc-leads { display: flex; flex-direction: column; }
.tc-lead { display: flex; flex-direction: column; gap: 3px; }
.tc-lead small { font-weight: 700; color: var(--muted); font-size: .75rem; }
.tc-team { padding: 6px 0; border-top: 1px solid var(--border); }
.tc-team-people { display: flex; flex-wrap: wrap; gap: 6px 14px; align-items: center; }
.tc-team-people .tc-vol-add { width: auto; max-width: 240px; }
.tc-team-people .chip-x { margin-left: 2px; }
.t-face { display: flex; align-items: center; gap: 10px; padding: 6px 0; border-top: 1px solid var(--border); flex-wrap: wrap; }
.t-face > div { flex: 1 1 14em; min-width: 0; overflow-wrap: anywhere; }
.t-face em { color: var(--muted); }
@media (max-width: 640px) {
  .tc-type { grid-template-columns: 56px minmax(0, 1fr) auto auto auto; }
  .tc-type .tt-line, .tc-type .tt-icon { grid-column: 1 / -1; }
  .join-faces-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ---------- Join the team (1.66.2): /join and the Account card ---------- */
.join-hero { background-size: cover; background-position: center; margin-top: 0; }
.join-kicker { display: inline-flex; align-items: center; gap: 6px; font-size: .75rem; font-weight: 900; text-transform: uppercase; letter-spacing: .06em; color: var(--esn-cyan); margin-bottom: 8px; }
.join-hero p { max-width: 640px; }
.join-cta-note { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; color: #fff; margin: 0; font-weight: 700; }
.join-cta-note a, .join-cta-note .linklike { color: #fff; }
.join-closed { background: rgba(255, 255, 255, .12); border-radius: var(--r-md); padding: 12px 14px; max-width: 560px; }
.join-closed p { color: #fff; margin: 0 0 6px; }
.join-stats { margin-top: 18px; }
.join-cols { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 14px; margin: 18px 0; }
.join-block { margin: 0; }
.join-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.join-list li { display: flex; gap: 8px; align-items: flex-start; }
.join-list li .material-symbols-rounded { color: var(--green-text); flex-shrink: 0; margin-top: 2px; }
.join-types { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 10px; margin-bottom: 18px; }
.join-type { display: flex; gap: 12px; align-items: flex-start; border: 1px solid var(--border); border-radius: var(--r-md); padding: 12px 14px; background: var(--card); }
.join-type-ic { width: 40px; height: 40px; border-radius: 12px; display: inline-grid; place-items: center; background: rgba(0, 174, 239, .14); color: var(--esn-cyan); flex-shrink: 0; }
.join-type small { color: var(--muted); }
.join-quotes { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 10px; margin-bottom: 18px; }
.join-quote { margin: 0; border-left: 4px solid var(--esn-magenta); padding: 8px 12px; background: var(--surface2); border-radius: 0 var(--r-md) var(--r-md) 0; font-style: italic; }
.join-next { margin-bottom: 18px; }
.join-tl { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.join-tl li { display: flex; gap: 10px; align-items: flex-start; color: var(--muted); }
.join-tl li strong { color: var(--ink); }
.join-tl li.done, .join-tl li.now { color: var(--ink); }
.join-tl-ic { width: 28px; height: 28px; border-radius: 50%; display: inline-grid; place-items: center; background: var(--surface2); color: var(--muted); flex-shrink: 0; }
.join-tl li.done .join-tl-ic { background: var(--esn-green); color: #fff; }
.join-tl li.now .join-tl-ic { background: var(--esn-cyan); color: #fff; box-shadow: 0 0 0 4px rgba(0, 174, 239, .2); }
.join-tl li small { color: var(--muted); }
.join-form { margin: 0 0 18px; }
.join-steps { display: flex; align-items: center; gap: 6px; margin-bottom: 14px; }
.join-steps span { width: 26px; height: 26px; border-radius: 50%; display: inline-grid; place-items: center; font-size: .8rem; font-weight: 700; background: var(--surface2); color: var(--muted); }
.join-steps span.now { background: var(--esn-dark); color: #fff; }
.join-steps span.done { background: var(--esn-green); color: #fff; }
.join-steps small { margin-left: 6px; color: var(--muted); font-weight: 700; }
.join-q { font-size: .9rem; margin: 16px 0 8px; }
.join-q small { color: var(--muted); font-weight: 400; }
.join-form .filter-chips { flex-wrap: wrap; overflow: visible; }  /* the answers wrap on a phone, they are not a scroller */
.join-form .chip { display: inline-flex; align-items: center; gap: 5px; }
.join-form .chip.active { color: #fff; }
.join-profile { display: flex; flex-direction: column; gap: 6px; background: var(--surface2); border-radius: var(--r-md); padding: 10px 12px; }
.join-profile-row { display: flex; gap: 8px; align-items: center; min-width: 0; overflow-wrap: anywhere; }
.join-profile-row > span:first-child { color: var(--muted); display: inline-flex; }
.join-miss { color: var(--esn-orange); font-style: normal; font-weight: 700; margin-left: 4px; }
.join-pledge { border: 1px solid var(--esn-green); border-radius: var(--r-md); padding: 12px 14px; background: rgba(122, 193, 67, .08); margin-bottom: 10px; }
.join-pledge p:first-child { margin: 0 0 6px; font-weight: 700; }
.join-pledge-tick { font-weight: 700; }
.join-nav { justify-content: space-between; margin-top: 16px; }
.join-done { text-align: center; }
.join-done-ic { font-size: 2.4rem; color: var(--esn-magenta); }
.join-done .join-tl { text-align: left; max-width: 420px; margin: 12px auto 0; }
.join-card { margin-bottom: 14px; }
.join-msg { border: 1px solid var(--border); border-left: 4px solid var(--esn-magenta); border-radius: var(--r-md); padding: 12px 14px; margin-bottom: 14px; background: var(--card); }
.join-msg-head { display: flex; gap: 10px; align-items: center; margin-bottom: 8px; }
.join-msg-text { line-height: 1.5; overflow-wrap: anywhere; }
.join-progress { height: 8px; border-radius: 999px; background: var(--surface2); overflow: hidden; margin: -4px 0 12px; }
.join-progress i { display: block; height: 100%; background: var(--esn-green); border-radius: 999px; width: 100%; transform: translateX(calc(var(--p, 0%) - 100%)); transition: transform .4s ease; }
.join-check { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 12px; }
.join-check li { display: flex; gap: 10px; align-items: flex-start; }
.join-check li.done { color: var(--muted); }  /* 1.78.4: was opacity .75 */
.join-check li.done strong { text-decoration: line-through; }
.join-check-ic { color: var(--muted); flex-shrink: 0; margin-top: 2px; }
.join-check li.done .join-check-ic { color: var(--green-text); }
.join-check small { color: var(--muted); }
.join-check-act { margin-top: 6px; display: flex; flex-wrap: wrap; gap: 6px; }
.join-first { display: flex; flex-direction: column; gap: 6px; margin-bottom: 4px; }
.join-first-row { display: flex; justify-content: space-between; align-items: center; gap: 8px; flex-wrap: wrap; border: 1px solid var(--border); border-radius: var(--r-md); padding: 8px 10px; }
.join-card-foot { justify-content: space-between; }
.join-card-perk { margin: 12px 0 0; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.join-app-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 8px 16px; }
.join-app-grid small { display: block; font-size: .75rem; text-transform: uppercase; letter-spacing: .4px; color: var(--muted); font-weight: 700; margin-bottom: 2px; }
.join-app-grid .tchip { margin: 2px 2px 0 0; }
.join-app-wide { grid-column: 1 / -1; white-space: pre-line; }
@media (max-width: 640px) {
  .join-cols { grid-template-columns: minmax(0, 1fr); }
  .join-app-grid { grid-template-columns: minmax(0, 1fr); }
  .join-hero { padding: 26px 20px 24px; }
}

/* ---------- The ESNcard page (1.68.0): /esncard, the bundle, the account bits ---------- */
.card-price-line { display: inline-flex; align-items: center; gap: 6px; flex-wrap: wrap; font-weight: 700; color: #fff; margin-bottom: 14px; }
.card-price-line .material-symbols-rounded { color: var(--esn-green); }
.card-cols .join-list small { color: var(--muted); font-weight: 400; }
.card-pts { position: relative; overflow: hidden; margin: 12px 0 4px; -webkit-mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent); mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent); }
.card-pts-track { display: flex; gap: 10px; width: max-content; padding: 4px 0 8px; }
.card-pts-track.run { animation: card-pts-slide var(--dur, 60s) linear infinite; }
.card-pts:hover .card-pts-track, .card-pts:focus-within .card-pts-track { animation-play-state: paused; }
@keyframes card-pts-slide { to { transform: translateX(-50%); } }
.card-pts.still { overflow-x: auto; scroll-snap-type: x mandatory; -webkit-mask-image: none; mask-image: none; scrollbar-width: thin; }
.card-pt { flex: 0 0 auto; width: 220px; display: flex; align-items: center; gap: 10px; padding: 8px 10px; border-radius: var(--r-md); background: var(--card); border: 1px solid var(--border); color: var(--ink); text-decoration: none; scroll-snap-align: start; }
.card-pt:hover { text-decoration: none; border-color: var(--esn-cyan); }
.card-pt-logo { flex: 0 0 44px; width: 44px; height: 44px; border-radius: 10px; background: #fff; border: 1px solid var(--border); display: grid; place-items: center; overflow: hidden; }
.card-pt-logo img { max-width: 86%; max-height: 86%; object-fit: contain; display: block; }
.card-pt-logo b { font-size: 1.05rem; font-weight: 900; color: var(--esn-dark); }
.card-pt-txt { min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.card-pt-txt strong { font-size: .85rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.card-pt-txt small { font-size: .75rem; color: var(--muted); display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; line-height: 1.25; }
.card-calc-row { display: flex; flex-direction: column; gap: 6px; margin-bottom: 10px; }
.card-calc-lbl { display: inline-flex; align-items: center; gap: 4px; font-weight: 700; font-size: .9rem; }
.card-calc-lbl small { color: var(--muted); font-weight: 400; }
.card-calc .filter-chips { flex-wrap: wrap; overflow: visible; }
.card-calc-out { margin: 12px 0 0; padding: 10px 12px; border-radius: var(--r-md); background: rgba(122, 193, 67, .12); border: 1px solid rgba(122, 193, 67, .4); font-size: .95rem; }
.card-calc-out small { display: block; color: var(--muted); font-size: .8rem; margin-top: 4px; }
.card-quote { grid-template-columns: minmax(0, 1fr); max-width: 760px; }
/* 1.69.3: the sample card lives in the hero now: text left, the card
   right (below the text on a phone). It arrives with a small turn, the
   foil sweeps across it once, then it floats and leans with the pointer
   or the phone (wireCardTilt). */
.card-hero-grid { display: grid; grid-template-columns: minmax(0, 1.05fr) minmax(0, .95fr); gap: 32px; align-items: center; }
.card-hero-text { min-width: 0; }
.card-hero-card { perspective: 1200px; min-width: 0; animation: hero-card-in .9s cubic-bezier(.2, .7, .3, 1) .15s both, hero-card-float 7s ease-in-out 1.4s infinite alternate; }
.card-hero-card .crew-kicker { color: #9fd9f6; margin: 0 0 10px; justify-content: center; }
.card-hero-card .esncard { max-width: 440px; margin: 0 auto; box-shadow: 0 30px 60px rgba(0, 0, 0, .45), 0 0 0 1px rgba(255, 255, 255, .08); }
.card-hero-tilt { transform-style: preserve-3d; }
.card-hero-tilt::before { animation: hero-foil 1.5s ease-in-out .8s both; }
.card-hero-hint { font-size: .75rem; color: #9fd9f6; text-align: center; margin: 12px 0 0; }
@keyframes hero-card-in { from { opacity: 0; transform: translateY(26px) rotateX(14deg) rotateY(-12deg) scale(.94); } to { opacity: 1; transform: none; } }
@keyframes hero-card-float { from { transform: translateY(0) rotateY(-1.5deg); } to { transform: translateY(-6px) rotateY(1.5deg); } }
@keyframes hero-foil { from { background-position: 135% 0; opacity: .5; } 60% { opacity: .5; } to { background-position: -35% 0; opacity: calc(var(--sheen, 0) * .42); } }
@media (max-width: 820px) {
  .card-hero-grid { grid-template-columns: minmax(0, 1fr); gap: 22px; }
  .card-hero-card .esncard { max-width: 400px; }
}
.card-faq { margin-bottom: 80px; }
.card-faq-item { border-top: 1px solid var(--border); padding: 8px 0; }
.card-faq-item summary { cursor: pointer; font-weight: 700; }
.card-faq-item p { margin: 6px 0 0; color: var(--muted); }
.card-sticky { position: fixed; left: 50%; bottom: calc(18px + env(safe-area-inset-bottom)); transform: translate(-50%, 20px); display: flex; align-items: center; gap: 14px; padding: 8px 10px 8px 16px; border-radius: 999px; background: var(--esn-dark); color: #fff; box-shadow: 0 10px 30px rgba(0, 0, 0, .3); z-index: 40; opacity: 0; pointer-events: none; transition: opacity .25s ease, transform .25s ease; max-width: calc(100vw - 32px); }
.card-sticky.on { opacity: 1; transform: translate(-50%, 0); pointer-events: auto; }
#app[data-enter] > .card-sticky { animation: none; }  /* 1.69.5: the entrance animated its opacity up, so the hidden bar flashed on arrival */
.ev-sticky .btn { white-space: nowrap; }
.ev-sticky strong { font-size: .95rem; }
.btn.cta-flash { animation: card-flash .9s ease 2; }  /* 1.69.5: the sticky bar points at the real button */
.card-sticky span { display: flex; flex-direction: column; line-height: 1.15; }
.card-sticky small { color: #c9ccee; font-size: .75rem; }
.card-missed { border-left: 4px solid var(--esn-green); margin-bottom: 14px; }
.card-friend { margin-bottom: 14px; }
.card-friend .esncard-line-x { align-self: flex-start; }
.bundle-box { margin: 0 0 10px; }
.bundle-pick { display: flex; gap: 10px; align-items: flex-start; padding: 10px 12px; border-radius: var(--r-md); border: 1px solid rgba(0, 174, 239, .45); background: rgba(0, 174, 239, .08); cursor: pointer; }
.bundle-pick input { margin-top: 3px; flex: none; }
.bundle-pick span { display: flex; flex-direction: column; gap: 2px; }
.bundle-pick small { color: var(--muted); font-size: .8rem; }
.bundle-pick:has(input:checked) { border-color: var(--esn-green); background: rgba(122, 193, 67, .12); }
.bundle-note { margin-top: 6px; font-size: .8rem; }
@media (max-width: 820px) {
  .card-sticky { gap: 10px; padding-left: 12px; bottom: calc(74px + env(safe-area-inset-bottom)); }
}
@media (max-width: 640px) {
}

/* ---------- One event's shiftlist (1.66.1): /shifts/<id> ---------- */
.sl-head { display: flex; flex-direction: column; gap: 12px; margin-bottom: 18px; }
.sl-sum { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.sl-acts { flex-wrap: wrap; }
.tchip.sl-open { background: rgba(244, 123, 32, .14); border-color: rgba(244, 123, 32, .5); color: var(--orange-text); }
.sl-open-card { border-color: var(--esn-green); box-shadow: inset 4px 0 0 var(--esn-green); margin-bottom: 18px; }
.sl-open-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.sl-open-list li { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 14px; padding-top: 10px; border-top: 1px solid var(--border); min-width: 0; overflow-wrap: anywhere; }
.sl-open-list li:first-child { padding-top: 0; border-top: 0; }
.sl-open-what { flex: 1 1 14em; min-width: 0; display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.sl-full { padding: 18px; margin-bottom: 18px; }
@media (max-width: 640px) {
  .sl-acts .btn { flex: 1 1 45%; justify-content: center; }
}

/* ---------- Shift cards (team view, v0.137) ---------- */
.shift-cards { display: flex; flex-direction: column; gap: 10px; }
.shift-card { border: 1px solid var(--border); border-radius: var(--r-md); padding: 12px 14px; background: var(--bg); min-width: 0; overflow-wrap: anywhere; }
.shift-card.mine { border-color: var(--esn-green); box-shadow: inset 4px 0 0 var(--esn-green); }
.shift-card.full:not(.mine) { opacity: .8; }
.shift-card-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.shift-card-head strong { font-size: 1rem; flex: 1 1 12em; min-width: 0; overflow-wrap: break-word; }  /* 1.58.0: a basis, so a long name takes its own line instead of being squeezed to a letter a line beside the time */
.shift-card .cell-note { margin: 6px 0 0; font-size: .8rem; color: var(--muted); }
.slot-row { display: flex; flex-wrap: wrap; gap: 6px; }
.shift-cards .slot-chip { min-height: 34px; display: inline-flex; align-items: center; }
.shift-fill.ok { color: var(--green-text); }  /* 1.29.4: one system */
/* 1.78.3: a grouped shift card: one name and note, then a line per time slot */
.shift-card.grouped .shift-seg { border-top: 1px dashed var(--border); padding: 8px 0 4px; margin-top: 8px; }
.shift-card.grouped .shift-seg.mine { box-shadow: inset 3px 0 0 var(--esn-green); padding-left: 10px; border-radius: 4px; }
.shift-card.grouped .shift-seg.full:not(.mine) { opacity: .8; }
.shift-seg-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.shift-seg .shift-slots { flex-direction: row; gap: 10px 18px; margin: 6px 0 0; }
.shift-seg .slot-group small { display: inline-block; margin: 0 6px 0 0; vertical-align: middle; }
.shift-seg .slot-row { display: inline-flex; vertical-align: middle; }

/* ---------- Board to-dos (v0.137) ---------- */
.todo-add-row { display: grid; grid-template-columns: 1fr auto auto auto; gap: 8px; margin: 0 0 12px; }
.todo-add-row .inline-input { width: 100%; min-width: 0; }
.todo-who { display: inline-flex; align-items: center; gap: 2px; font-weight: 700; }
.todo-due { display: inline-flex; align-items: center; gap: 2px; font-weight: 700; }
.todo-claim-ico { width: 17px; margin-top: 3px; color: var(--muted); flex-shrink: 0; }
.publish-state { display: inline-flex; align-items: center; gap: 6px; margin-right: 4px; }
.todo-due.soon { color: var(--orange-text); }
.todo-due.overdue { color: var(--danger); }
.todo-who.me { color: var(--green-text); }  /* 1.32.0: board pages measured for the first time */
@media (max-width: 560px) {
  .todo-add-row { grid-template-columns: 1fr 1fr; }  /* 1.1.13: Election ballot */
  .todo-add-row #todo-new, .todo-add-row #todo-add { grid-column: 1 / -1; }
}

/* ---------- Admin event header (1.1.15) ---------- */
/* Admin event header (1.1.15) */
.ev-head { padding: 16px 18px 0; }
.ev-head-top { display: flex; flex-wrap: wrap; gap: 10px 16px; align-items: flex-start; justify-content: space-between; }
.ev-head-title { min-width: 0; flex: 1 1 280px; }
.ev-head-badges { margin-top: 6px; display: flex; flex-wrap: wrap; gap: 6px; }
.ev-head-actions { display: flex; flex-wrap: wrap; gap: 8px; }
.ev-head-info { margin: 12px 0 8px; }
.ev-head-sync { display: inline-flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.ev-head-info li { align-items: center; gap: 10px; }  /* 1.78.7: icon labels */
.ev-head-info .info-ico { width: 28px; height: 28px; border-radius: var(--r-sm); }
.ev-tabs { display: flex; overflow-x: auto; scrollbar-width: none; margin: 4px -18px 0; padding: 0 18px; border-top: 1px solid var(--border); }
.ev-tabs a { display: inline-flex; align-items: center; gap: 4px; padding: 10px 12px; font-weight: 700; color: var(--muted); border-bottom: 2px solid transparent; text-decoration: none; }
.ev-tabs a.active { color: var(--accent-text); border-bottom-color: var(--accent-text); }
.ev-tabs a:hover { text-decoration: none; color: var(--ink); }
tr.attn-soon > td:first-child { border-left: 3px solid var(--esn-orange); }
.ev-year-pick { margin-left: auto; display: inline-flex; align-items: center; gap: 6px; }
.todo-claim { margin-left: auto; white-space: nowrap; }
@media (max-width: 640px) {
  .ev-head { padding: 14px 14px 0; }
  .ev-tabs { margin: 4px -14px 0; padding: 0 6px; }
  .ev-tabs a { padding: 10px 8px; font-size: .85rem; }
  .ev-year-pick { margin-left: 0; }
}

/* ---------- Election ballot (1.1.13) ---------- */
/* Election ballot (1.1.13) */
.el-role { padding: 12px 0; border-bottom: 1px solid var(--border); }
.el-role:last-of-type { border-bottom: none; }
.el-head { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; }
.el-head strong { font-size: 1rem; }
.el-head .el-role-del { margin-left: auto; padding: 2px 8px; }
.el-cands { display: flex; flex-direction: column; gap: 6px; margin-bottom: 8px; }
.el-cand { display: flex; align-items: center; gap: 8px; }
.el-cand .el-cname { flex: 1; min-width: 0; }
.el-cand .el-votes { width: 72px; }
.el-cand .el-cand-del { padding: 2px 8px; }
.el-cands .el-cand-add { align-self: flex-start; }
.el-tally { display: flex; flex-wrap: wrap; gap: 8px 16px; align-items: center; margin-bottom: 8px; font-size: .85rem; font-weight: 700; color: var(--muted); }
.el-tally label { display: inline-flex; align-items: center; gap: 6px; }
.el-tally input[type="number"] { width: 68px; }
.el-tally select { min-width: 170px; }
.el-role .el-note { width: 100%; }
.el-add-row { margin-top: 12px; }
.el-add-row select { min-width: 200px; }
@media (max-width: 560px) {
  .el-tally label { flex: 1 1 45%; }
  .el-tally select { min-width: 0; flex: 1; }
}

/* ---------- Admin dashboard (v0.137) ---------- */
/* 1.78.17: the desk, reworked after the owner's first look ("still outdated", "make the AI block smooth",
   "Latest like a timeline"). A navy hero with Find or Ask Jacob as a command bar and Create (no greeting:
   the home page has it);
   Needs you; the live feed as a timeline beside Coming up (calendar dates) and Tickets per event. */
.desk-hero {
  margin: 0 0 18px; padding: 20px 20px 18px; border-radius: var(--r-lg); color: #fff; box-shadow: var(--shadow-lg);
  background: radial-gradient(circle at 95% -10%, rgba(0, 174, 239, .38), transparent 42%), radial-gradient(circle at 72% 135%, rgba(236, 0, 140, .26), transparent 46%), var(--navy-gradient);
}
.desk-hero-top { display: flex; align-items: center; gap: 12px; margin: 0 0 14px; }
.desk-create { flex: none; margin-left: auto; }
.desk-create > summary { box-shadow: 0 4px 14px rgba(0, 0, 0, .22); }
.desk-create-list > a > span { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.desk-create-list small { color: var(--muted); font-weight: 500; font-size: .75rem; }
.desk-field { position: relative; display: flex; align-items: center; gap: 4px; background: var(--card); color: var(--ink); border-radius: var(--r-md); box-shadow: 0 8px 24px rgba(8, 10, 40, .28); transition: box-shadow var(--dur-fast) var(--ease-settle); }
.desk-field:focus-within { box-shadow: 0 0 0 3px rgba(77, 208, 255, .6), 0 8px 24px rgba(8, 10, 40, .28); }
.desk-field > .material-symbols-rounded:first-child, .desk-field > .jacob-sm { margin-left: 14px; flex: none; color: var(--muted); }
.desk-field input { flex: 1; min-width: 0; height: 52px; border: 0; outline: none; background: transparent; padding: 0 8px; font: inherit; font-size: 1rem; color: var(--ink); box-shadow: none; }
.desk-field input:disabled { cursor: not-allowed; background: transparent; }
.desk-kbd { margin-right: 12px; padding: 1px 7px; border: 1px solid var(--border); border-bottom-width: 2px; border-radius: 6px; font: inherit; font-size: .75rem; font-weight: 700; color: var(--muted); }
@media (hover: none), (max-width: 700px) {
  .desk-kbd { display: none; }
}
.desk-send { flex: none; margin-right: 6px; width: 40px; height: 40px; border: 0; border-radius: 10px; background: var(--accent-text); color: var(--card); display: inline-flex; align-items: center; justify-content: center; cursor: pointer; transition: background var(--dur-quick) var(--ease-settle), transform var(--dur-quick) var(--ease-pop); }
.desk-send:not(:disabled):hover { transform: translateY(-1px); }
.desk-send:disabled { background: var(--surface2); color: var(--muted); cursor: default; }
.desk-send.is-busy { background: var(--accent-text); color: var(--card); }
.desk-send.is-busy .material-symbols-rounded { animation: spin .9s linear infinite; }
.desk-results { margin-top: 8px; padding: 6px; background: var(--card); color: var(--ink); border-radius: var(--r-md); box-shadow: var(--shadow-lg); }
.desk-results:empty { display: none; }
.desk-results > .form-hint { margin: 6px 8px; }
.desk-res-h { margin: 6px 8px 2px; font-size: .75rem; font-weight: 800; letter-spacing: .6px; text-transform: uppercase; color: var(--muted); }
.desk-res { list-style: none; margin: 0; padding: 0; }
.desk-hit { display: flex; align-items: center; gap: 10px; padding: 7px 8px; border-radius: var(--r-sm); color: var(--ink); text-decoration: none; }
.desk-hit:hover, .desk-hit:focus-visible { background: var(--hover); text-decoration: none; }
.desk-hit > span:last-child { display: flex; flex-direction: column; min-width: 0; }
.desk-hit strong { font-size: .9rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.desk-hit small { color: var(--muted); font-size: .75rem; overflow-wrap: anywhere; }
.desk-hit > .material-symbols-rounded { color: var(--muted); width: 28px; text-align: center; flex: none; }
.desk-cats { display: flex; gap: 6px; overflow-x: auto; scrollbar-width: none; margin: 0 0 10px; padding: 2px; }
.desk-cats::-webkit-scrollbar { display: none; }
.desk-cats > button { flex: none; display: inline-flex; align-items: center; gap: 5px; padding: 7px 12px; border-radius: 999px; border: 1px solid rgba(255, 255, 255, .24); background: rgba(255, 255, 255, .08); color: #fff; font: inherit; font-size: .8rem; font-weight: 700; cursor: pointer; transition: background var(--dur-quick) var(--ease-settle), color var(--dur-quick) var(--ease-settle); }
.desk-cats > button:hover { background: rgba(255, 255, 255, .16); }
.desk-cats > button[aria-pressed="true"] { background: #fff; color: var(--esn-dark); border-color: #fff; }
.desk-cats > button:focus-visible, .pill-seg.on-dark > button:focus-visible { outline: 2px solid var(--cyan-on-dark); outline-offset: 2px; }
.desk-ask-hint { margin: 8px 2px 0; font-size: .8rem; color: rgba(255, 255, 255, .82); }
.desk-ask-hint a { color: var(--cyan-on-dark); }
.desk-link { border: 0; background: none; padding: 0; font: inherit; color: var(--cyan-on-dark); font-weight: 800; text-decoration: underline; cursor: pointer; }
.desk-answer { margin-top: 12px; background: var(--card); color: var(--ink); border-radius: var(--r-md); box-shadow: var(--shadow-lg); overflow: hidden; animation: daOpen var(--dur-fast) var(--ease-settle); }
@keyframes daOpen { from { opacity: 0; transform: translateY(-6px) scale(.99); } }
.da-think { display: flex; align-items: center; gap: 12px; padding: 14px 16px; }
.da-orb { width: 22px; height: 22px; flex: none; border-radius: 50%; background: conic-gradient(var(--esn-cyan), var(--esn-magenta), var(--esn-orange), var(--esn-green), var(--esn-cyan)); -webkit-mask: radial-gradient(circle, transparent 52%, #000 54%); mask: radial-gradient(circle, transparent 52%, #000 54%); animation: spin 1.1s linear infinite; }
.da-step { font-weight: 700; font-size: .9rem; color: var(--muted); }
.da-step.da-in { animation: daStep .35s var(--ease-settle); }
@keyframes daStep { from { opacity: 0; transform: translateY(4px); } }
.da-card { padding: 14px 16px 12px; }
.da-head { display: flex; align-items: center; gap: 10px; }
.da-who { display: flex; flex-direction: column; min-width: 0; flex: 1; }
.da-who strong { font-size: .9rem; }
.da-who span { font-size: .8rem; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.da-text { margin: 10px 0 4px; font-size: .95rem; line-height: 1.55; }
.da-foot { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; padding-top: 10px; margin-top: 8px; border-top: 1px solid var(--border); }
.da-note { margin: 0 0 0 auto; }
.da-facts summary { cursor: pointer; font-size: .8rem; color: var(--muted); font-weight: 700; padding: 4px 0; }
.da-facts pre { max-height: 220px; overflow: auto; font-size: .75rem; background: var(--surface2); padding: 8px; border-radius: var(--r-sm); white-space: pre-wrap; }
/* a segmented control in one pill (the app's .seg is the bordered one of the forms) (the window, the kinds of Latest, Find or Ask) */
.pill-seg { display: inline-flex; gap: 2px; padding: 3px; border-radius: 999px; background: var(--surface2); max-width: 100%; overflow-x: auto; scrollbar-width: none; }
.pill-seg::-webkit-scrollbar { display: none; }
.pill-seg > button { flex: none; display: inline-flex; align-items: center; gap: 4px; border: 0; background: none; font: inherit; font-size: .8rem; font-weight: 700; color: var(--muted); padding: 6px 12px; border-radius: 999px; cursor: pointer; transition: background var(--dur-quick) var(--ease-settle), color var(--dur-quick) var(--ease-settle); }
.pill-seg > button:hover { color: var(--ink); }
.pill-seg > button[aria-pressed="true"] { background: var(--card); color: var(--ink); box-shadow: var(--shadow); }
.pill-seg > button:focus-visible { outline: 2px solid var(--accent-text); outline-offset: 1px; }
.pill-seg.on-dark { background: rgba(255, 255, 255, .12); }
.pill-seg.on-dark > button { color: rgba(255, 255, 255, .9); }
.pill-seg.on-dark > button:hover { color: #fff; }
.pill-seg.on-dark > button[aria-pressed="true"] { background: #fff; color: var(--esn-dark); }
/* the cards below the hero */
.desk-grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: 16px; align-items: start; }
.desk-grid .form-card { margin: 0; border-radius: var(--r-lg); padding: 18px; }
.desk-side { display: flex; flex-direction: column; gap: 16px; min-width: 0; }
@media (min-width: 1000px) {
  .desk-grid { grid-template-columns: minmax(0, 1.7fr) minmax(0, 1fr); }
}
.desk-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin: 0 0 14px; }
.desk-head > strong { font-size: 1.05rem; }
.desk-ico { width: 32px; height: 32px; flex: none; border-radius: 10px; display: inline-flex; align-items: center; justify-content: center; color: var(--kc); background: color-mix(in srgb, var(--kc) 14%, transparent); }
.desk-head-end { margin-left: auto; }
.desk-head-link { font-size: .85rem; font-weight: 700; }
.live-state { display: inline-flex; align-items: center; gap: 6px; font-size: .8rem; color: var(--muted); }
.live-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--esn-green); animation: livePulse 2.4s var(--ease-settle) infinite; }
.live-state.is-off .live-dot { background: var(--muted); animation: none; }
@keyframes livePulse { 0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--esn-green) 55%, transparent); } 70% { box-shadow: 0 0 0 7px transparent; } 100% { box-shadow: 0 0 0 0 transparent; } }
.live-sub { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin: 18px 0 10px; }
.live-sub .recent-sub { margin: 0; }
#live-kinds-box { min-width: 0; max-width: 100%; }
/* Latest as a timeline: one line, a dot per record, the group's day as a label on it */
.tl-group + .tl-group { margin-top: 8px; }
.lf-grp { display: inline-block; margin: 0 0 4px; padding: 2px 10px; border-radius: 999px; background: var(--surface2); font-size: .7rem; font-weight: 800; letter-spacing: .6px; text-transform: uppercase; color: var(--muted); }
.tl { list-style: none; margin: 0; padding: 0; position: relative; }
.tl::before { content: ""; position: absolute; left: 15px; top: 10px; bottom: 10px; width: 2px; border-radius: 1px; background: var(--border); }
.tl-item { --kc: var(--muted); position: relative; display: grid; grid-template-columns: 32px minmax(0, 1fr); gap: 12px; align-items: start; padding: 6px 0; }
.tl-item[data-kind="tickets"], .tl-item[data-kind="shop"] { --kc: var(--esn-cyan); }
.tl-item[data-kind="checkins"], .tl-item[data-kind="shifts"] { --kc: var(--esn-green); }
.tl-item[data-kind="cards"], .tl-item[data-kind="people"] { --kc: var(--esn-magenta); }
.tl-item[data-kind="messages"], .tl-item[data-kind="refunds"], .tl-item[data-kind="ratings"] { --kc: var(--esn-orange); }
.tl-dot { position: relative; z-index: 1; width: 32px; height: 32px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; color: var(--kc); background: color-mix(in srgb, var(--kc) 14%, var(--card)); box-shadow: 0 0 0 3px var(--card); }
.tl-body { display: flex; flex-direction: column; gap: 1px; min-width: 0; padding-top: 3px; }
.tl-text { font-size: .9rem; line-height: 1.4; color: var(--ink); text-decoration: none; overflow-wrap: anywhere; }
a.tl-text:hover { text-decoration: underline; }
html[data-theme="dark"] a.tl-text, html[data-theme="dark"] a.soon-row, html[data-theme="dark"] a.desk-hit { color: var(--ink); }  /* rows read as text; the dark theme's cyan is for links in prose */
.tl-meta { font-size: .75rem; color: var(--muted); }
.tl-item.lf-new { animation: lfIn .7s var(--ease-settle); }
.tl-item.lf-new .tl-dot { animation: tlPing 1.2s var(--ease-settle) 2; }
@keyframes lfIn { from { opacity: 0; transform: translateY(-8px); } }
@keyframes tlPing { 0% { box-shadow: 0 0 0 3px var(--card), 0 0 0 3px color-mix(in srgb, var(--kc) 55%, transparent); } 100% { box-shadow: 0 0 0 3px var(--card), 0 0 0 13px transparent; } }
.kpi.kpi-bump { animation: kpiBump .7s var(--ease-pop); }
@keyframes kpiBump { 0% { transform: none; } 35% { transform: scale(1.04); box-shadow: 0 0 0 3px color-mix(in srgb, var(--esn-cyan) 40%, transparent); } 100% { transform: none; } }
/* Coming up: a calendar date per event */
.soon-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.soon-list li + li { border-top: 1px solid var(--border); }
.soon-row { display: grid; grid-template-columns: 44px minmax(0, 1fr) auto; gap: 12px; align-items: center; padding: 9px 6px; border-radius: var(--r-sm); color: var(--ink); text-decoration: none; }
.soon-row:hover { background: var(--hover); text-decoration: none; }
.soon-date { width: 44px; height: 46px; border-radius: 10px; display: flex; flex-direction: column; align-items: center; justify-content: center; line-height: 1; background: color-mix(in srgb, var(--c, var(--esn-cyan)) 12%, var(--card)); border: 1px solid color-mix(in srgb, var(--c, var(--esn-cyan)) 30%, transparent); }
.soon-date b { font-size: 1.15rem; font-weight: 900; color: var(--ink); }
.soon-date small { margin-top: 3px; font-size: .66rem; font-weight: 800; letter-spacing: .5px; text-transform: uppercase; color: var(--muted); }
.soon-main { display: flex; flex-direction: column; min-width: 0; }
.soon-main strong { font-size: .9rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.soon-main small, .soon-nums small { color: var(--muted); font-size: .75rem; }
.soon-nums { display: flex; flex-direction: column; align-items: flex-end; gap: 2px; text-align: right; font-size: .85rem; }
.soon-nums .sold-bar { width: 74px; }
.needs-n { display: inline-flex; align-items: center; justify-content: center; min-width: 20px; height: 20px; padding: 0 6px; margin-left: 6px; border-radius: 10px; background: var(--magenta-deep); color: #fff; font-size: .7rem; font-weight: 900; letter-spacing: 0; vertical-align: 1px; }
/* 1.78.17: the tabs' marker for numbers out of sight (paintTabsWaiting): it sticks to the row's right end */
.tabs-waiting { display: none; }
.tabs-waiting:not([hidden]) { position: sticky; right: 0; z-index: 1; margin-left: auto; flex: none; align-self: center; display: inline-flex; align-items: center; gap: 2px; padding: 3px 4px 3px 6px; border-radius: 999px; border: 1px solid color-mix(in srgb, var(--magenta-deep) 55%, var(--border)); color: var(--magenta-text); background: var(--card); box-shadow: -14px 0 12px 4px var(--bg); cursor: pointer; }
.admin-tabs:has(.tabs-waiting:not([hidden])) { -webkit-mask-image: none; mask-image: none; }  /* the marker says there is more; the edge fade would dim it */
.tabs-waiting b { display: inline-flex; align-items: center; justify-content: center; min-width: 20px; height: 20px; padding: 0 6px; border-radius: 10px; background: var(--magenta-deep); color: #fff; font-size: .7rem; font-weight: 900; }
/* 1.78.17: the Events tab in groups (week, month, tag, status): a heading row starts each group */
tr.ev-grp th { background: var(--surface2); color: var(--ink); text-transform: none; letter-spacing: 0; font-size: .85rem; padding: 8px 16px; border-bottom: 1px solid var(--border); }
.ev-grp-n { color: var(--muted); font-weight: 500; margin-left: 6px; }
.filter-bar .ev-group-pick select { width: auto; min-width: 118px; height: 36px; margin-left: 4px; border-radius: var(--r-sm); border: 1px solid var(--border); background: var(--card); color: var(--ink); font: inherit; font-size: .85rem; padding: 0 26px 0 8px; }
.attn-row { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 14px; }
.attn-row:empty { display: none; }
.attn { display: inline-flex; align-items: center; gap: 6px; padding: 8px 12px; border-radius: 999px; background: rgba(244, 123, 32, .12); border: 1px solid rgba(244, 123, 32, .5); color: var(--ink); font-size: .85rem; text-decoration: none; }
.attn:hover { text-decoration: none; background: rgba(244, 123, 32, .2); }
.attn.muted { background: var(--card); border-color: var(--border); color: var(--muted); }
/* A paragraph notice is a block of text, not a pill: the text flows, the
   button (if any) sits at its right end. The pills in the Needs-you row keep
   their shape. */
p.attn { display: flow-root; border-radius: var(--r-md); padding: 10px 14px; line-height: 1.45; }  /* 1.14.1: one button */
p.attn > .material-symbols-rounded { vertical-align: -4px; margin-right: 2px; }
p.attn > .btn { float: right; margin: -3px 0 4px 12px; }
.recent-card { margin: 0 0 18px; }  /* 1.33.0: What happened */
.recent-kpis { margin: 4px 0 14px; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); }
/* 1.51.0: on a wide screen the tiles share full rows (10 tiles: 5 + 5, not 7 + 3) */
@media (min-width: 900px) { .recent-kpis { grid-template-columns: repeat(var(--cols, 6), minmax(0, 1fr)); } }
.recent-kpis .kpi { min-height: 0; padding: 12px 14px; background: var(--card); border: 1px solid var(--border); display: grid; grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: "l i" "n n" "h h"; column-gap: 8px; row-gap: 2px; align-items: start; }  /* 1.78.17: label, number, hint; the icon in a tinted square */
.recent-kpis .kpi-i { grid-area: i; width: 30px; height: 30px; border-radius: 9px; display: inline-flex; align-items: center; justify-content: center; background: color-mix(in srgb, var(--esn-cyan) 13%, transparent); }
.recent-kpis .kpi-l { grid-area: l; color: var(--muted); font-size: .75rem; align-self: center; }
.recent-kpis .kpi-h { grid-area: h; }
.recent-kpis .kpi-n { grid-area: n; font-size: 1.45rem; }
.recent-sub { margin: 0 0 8px; font-weight: 800; font-size: .9rem; display: flex; align-items: center; gap: 6px; }
.recent-events { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.recent-events li a { display: grid; grid-template-columns: minmax(0, 1fr); gap: 3px; text-decoration: none; color: inherit; padding: 6px 8px; border-radius: var(--r-sm); }
.recent-events li a:hover { background: var(--hover); }
.recent-events .re-title { font-weight: 700; font-size: .9rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.recent-events .re-bar { display: block; height: 6px; border-radius: 3px; background: var(--surface2); position: relative; overflow: hidden; }
.recent-events .re-bar::after { content: ""; position: absolute; inset: 0; width: var(--w); background: var(--esn-cyan); border-radius: 3px; }
.recent-events .re-n { font-size: .8rem; color: var(--muted); }
@media (max-width: 640px) {
  p.attn > .btn { float: none; display: flex; width: 100%; margin: 8px 0 0; }  /* 1.14.1: one button */
}

/* ---------- Admin home: "Needs you" first (1.10.0) ---------- */
/* Needs you: a list, not a row of boxes */
.needs-you { margin: 0 0 16px; background: var(--card); border: 1px solid var(--border); box-shadow: var(--shadow); border-radius: var(--r-lg); padding: 10px 6px 4px; }
.needs-you-head { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; padding: 0 10px; margin-bottom: 4px; }
/* Admin home (1.15.0): what needs you is a list, one row each, not a pile of
   pills of every width. Actionable rows keep the orange tint, waiting rows
   are plain, a link ends in a chevron. */
.needs-you .attn-row { margin: 0; flex-direction: column; align-items: stretch; gap: 0; }
.needs-you .attn-row:empty { display: none; }
.glance summary .form-hint { margin-left: 6px; }
/* the rows carry an inline border-color for the old pill look; the card
   look keeps one grey frame and puts the urgency in the left bar */
.needs-you .attn { display: flex; width: 100%; box-sizing: border-box; line-height: 1.35; font-size: .9rem; --bar: var(--esn-orange); background: transparent; border: 0 !important; box-shadow: none; border-radius: 10px; padding: 9px 10px; gap: 10px; }  /* 1.15.0: colours per category */
.needs-you .attn > .material-symbols-rounded { flex: none; width: 30px; height: 30px; border-radius: 9px; display: inline-flex; align-items: center; justify-content: center; font-size: 16px; color: var(--bar); background: color-mix(in srgb, var(--bar) 14%, transparent); }
.needs-you .attn-txt { flex: 1; min-width: 0; }  /* 1.51.0: the number and its words in one span, so every row has the same gap */
.needs-you .attn-txt > strong { font-size: 1rem; margin-right: 2px; }
.needs-you a.attn::after, .needs-you button.attn::after { content: "\203A"; margin-left: auto; padding-left: 8px; color: var(--muted); font-size: 1.15rem; line-height: 1; }
.needs-you .attn.muted::after { color: var(--muted); }
.needs-you-head strong { font-size: .8rem; letter-spacing: .6px; text-transform: uppercase; color: var(--muted); }  /* 1.18.0: admin dashboard */
.needs-you .attn:hover { background: var(--hover); }
.needs-you .attn[style*="--danger"] { --bar: var(--danger); }
.needs-you .attn[style*="--esn-magenta"] { --bar: var(--esn-magenta); }
.needs-you .attn.muted { --bar: var(--border); color: var(--muted); }
.needs-you .attn + .attn { border-top: 1px solid var(--border) !important; border-radius: 0; }  /* 1.28.0: the toolbar */
.needs-you .attn.muted > .material-symbols-rounded { --bar: var(--muted); }
.needs-you a.attn:hover, .needs-you button.attn:hover { background: var(--hover); }
/* 1.58.0: a row that opens a sheet looks and reads like a row that opens a page */
.needs-you button.attn { font: inherit; font-size: .9rem; color: var(--ink); text-align: left; cursor: pointer; }
.needs-you button.attn.muted { color: var(--muted); }
.needs-sheet { width: min(640px, 100%); max-height: calc(100dvh - 32px); overflow-y: auto; }
.ns-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.ns-head h3 { display: flex; align-items: center; gap: 8px; }
.ns-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.ns-row { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 4px 12px; align-items: center; padding: 12px 0; border-top: 1px solid var(--border); }
.ns-row:first-child { border-top: 0; }
.ns-txt { display: flex; flex-direction: column; min-width: 0; }
.ns-txt strong { overflow-wrap: anywhere; }
.ns-txt small { color: var(--muted); font-size: .8rem; }
.ns-acts { grid-column: 2; display: flex; flex-wrap: wrap; gap: 6px; margin-top: 4px; }
@media (min-width: 900px) {
  .needs-you .attn-row { display: grid; grid-template-columns: 1fr 1fr; column-gap: 12px; }
  .needs-you .attn + .attn { border-top: 0 !important; }
  .needs-you .attn { border-bottom: 1px solid var(--border) !important; }
  .needs-you .attn[data-last] { border-bottom: 0 !important; }
}

/* ---------- Account membership card (v0.137) ---------- */
.acct-state { margin: 0 0 8px; display: flex; gap: 6px; flex-wrap: wrap; }
.acct-state .badge { display: inline-flex; align-items: center; gap: 4px; padding: 6px 10px; font-size: .8rem; }
.acct-note { margin: 0 0 10px; font-size: .9rem; line-height: 1.45; }
.acct-member .form-actions { margin: 0; }
.acct-member .form-hint { margin: 8px 0 0; }
.menu-lock { font-weight: 400; text-transform: none; letter-spacing: 0; color: var(--muted); display: inline-flex; align-items: center; gap: 2px; margin-left: 6px; }
/* Phone: the app bar arrow is the back button, the hero does not repeat it */
/* Account without a card (1.29.3): the card face says it once, the block
   under it sells the card with three perks instead of a grey badge. */
.esncard-nocard {
  align-items: center; gap: 6px; margin-top: 4px; padding: 7px 10px; border-radius: var(--r-sm);
  background: rgba(46, 49, 146, .07); color: #4a4d7a; font-size: .75rem; font-weight: 700;
}  /* 1.29.3: event page polish */
.esncard-nocard .material-symbols-rounded { font-size: 16px; }
.getcard-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin: 0 0 10px; }
.getcard-head > div { display: flex; flex-direction: column; gap: 1px; }
.getcard-head strong { font-size: 1.05rem; }
.getcard-head small { color: var(--muted); font-size: .8rem; }
.getcard-price { font-weight: 900; font-size: 1.15rem; white-space: nowrap; color: var(--magenta-text); }
.getcard-perks { list-style: none; margin: 0 0 14px; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.getcard-perks li { display: flex; align-items: center; gap: 10px; font-size: .9rem; }
.getcard-ic {
  width: 30px; height: 30px; border-radius: 9px; flex: none; display: inline-flex; align-items: center; justify-content: center;
  background: color-mix(in srgb, var(--esn-cyan) 14%, transparent); color: var(--esn-cyan);
}
.acct-getcard .btn-block { margin: 0; }
.acct-getcard .acct-details { margin-top: 12px; }
.esncard-nocard a { color: var(--magenta-text); }  /* 1.29.4: one system */
.acct-note a.magenta { color: var(--magenta-text); }

/* ---------- Office page (v0.137) ---------- */
.office-hero { display: flex; align-items: center; justify-content: space-between; gap: 14px; flex-wrap: wrap; padding: 16px 18px; border-radius: var(--radius); background: var(--card); border: 1px solid var(--border); border-left: 5px solid var(--esn-cyan); box-shadow: var(--shadow); margin-bottom: 16px; }
.office-hero.open { border-left-color: var(--esn-green); }
.office-hero-main { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.office-kicker { font-size: .8rem; font-weight: 700; text-transform: uppercase; letter-spacing: .4px; color: var(--muted); }
.office-hero-main strong { font-size: 1.15rem; }
.office-hero-main small { color: var(--muted); }
.office-hero-acts { display: flex; flex-wrap: wrap; gap: 8px; }  /* 1.72.0 */
.office-duty { margin: -6px 0 14px; }
.office-mine { border-left: 5px solid var(--esn-green); margin-bottom: 16px; }
.office-mine .office-facts { margin: 10px 0 8px; }
/* 1.73.0: the housing guide (/housing) */
.hz-page { max-width: var(--w-wide); margin: 0 auto; }
.hz-hero { position: relative; overflow: hidden; background: var(--card); border: 1px solid var(--border); border-radius: var(--radius); box-shadow: var(--shadow); padding: 18px 20px; margin-bottom: 14px; border-top: 5px solid var(--esn-green); }
.hz-hero-top { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; }
.hz-kicker { font-size: .8rem; font-weight: 800; letter-spacing: .05em; text-transform: uppercase; color: var(--muted); display: inline-flex; align-items: center; gap: 5px; }
.hz-hero-acts { display: inline-flex; gap: 6px; flex-wrap: wrap; }
.hz-hero h2 { font-size: 1.7rem; font-weight: 900; margin: 6px 0 12px; color: var(--ink); }
.hz-facts { display: grid; grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr)); gap: 8px; margin-bottom: 12px; align-items: stretch; }
.hz-facts > div { background: var(--surface2); border-radius: var(--r-md); padding: 10px 12px; display: flex; flex-direction: column; gap: 2px; }
.hz-facts b { font-size: 1.3rem; font-weight: 900; color: var(--accent-text); font-variant-numeric: tabular-nums; }
.hz-facts span { font-size: .8rem; color: var(--muted); line-height: 1.3; }
.hz-lead p { margin: 0 0 8px; line-height: 1.55; }
.hz-updated { font-size: .8rem; color: var(--muted); margin: 6px 0 0; display: flex; align-items: center; gap: 5px; flex-wrap: wrap; }
.hz-editbar { display: flex; gap: 8px; align-items: flex-start; background: var(--surface2); border: 1px dashed var(--esn-magenta); border-radius: var(--r-md); padding: 8px 12px; margin-bottom: 12px; font-size: .8rem; }
.hz-editbar code { font-size: .8rem; }
.hz-nav { position: sticky; top: 56px; z-index: 5; display: flex; gap: 6px; overflow-x: auto; padding: 8px 0; margin-bottom: 6px; background: var(--bg); scrollbar-width: none; }
.hz-nav::-webkit-scrollbar { display: none; }
.hz-nav .chip { flex: none; }
.hz-sec { margin: 10px 0 26px; scroll-margin-top: 110px; }
.hz-sec > .section-title { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.hz-sec > p { line-height: 1.55; }
.hz-edit { margin-left: auto; }
.hz-tools { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin: 6px 0 10px; }
.hz-campus { display: inline-flex; align-items: center; gap: 6px; background: var(--card); border: 1px solid var(--border); border-radius: 999px; padding: 4px 6px 4px 12px; max-width: 100%; }
.hz-campus select { border: 0; background: transparent; font: inherit; font-weight: 700; color: var(--ink); min-width: 0; max-width: 70vw; padding: 6px 4px; }
.hz-edit-tools { display: inline-flex; gap: 6px; flex-wrap: wrap; margin-left: auto; }
.hz-drawbar { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; background: var(--surface2); border: 1px solid var(--esn-magenta); border-radius: var(--r-md); padding: 8px 10px; margin-bottom: 8px; font-size: .85rem; }
.hz-drawbar span { flex: 1; min-width: 12rem; }
.hz-mapwrap { border-radius: var(--radius); overflow: hidden; border: 1px solid var(--border); box-shadow: var(--shadow); }
.hz-mapbox { height: 440px; background: var(--surface2); }
.hz-mapbox.drawing { cursor: crosshair; }
.hz-mapbox.drawing .leaflet-interactive { cursor: crosshair; }
.hz-map-off { padding: 18px; margin: 0; display: flex; gap: 6px; align-items: center; }
.hz-zn-wrap, .hz-pin-wrap { background: none; border: 0; }
.hz-zn { display: inline-flex; align-items: center; justify-content: center; width: 26px; height: 26px; border-radius: 50%; background: var(--c, var(--esn-dark)); color: #fff; font-weight: 900; font-size: .8rem; box-shadow: 0 0 0 2px #fff, 0 2px 6px rgba(0, 0, 0, .25); flex: none; }
.hz-pin { display: inline-flex; align-items: center; justify-content: center; width: 30px; height: 30px; border-radius: 50%; background: var(--card); color: var(--esn-dark); border: 2px solid var(--esn-dark); box-shadow: 0 2px 6px rgba(0, 0, 0, .25); }
.hz-pin-station { border-color: #6d6f78; color: #3c3e46; }
.hz-pin-campus { border-color: var(--esn-cyan); color: #0a86b8; }
.hz-pin-office { border-color: var(--esn-magenta); color: var(--esn-magenta); }
.hz-pin-dorm { border-color: var(--esn-green); color: #3f8a1a; }
.hz-pin.hz-me { background: var(--esn-cyan); color: #fff; border-color: #fff; width: 34px; height: 34px; }
.hz-zone-detail { margin-top: 10px; }
.hz-zone-card { border-left: 5px solid var(--c); }
.hz-zone-head { display: flex; align-items: center; gap: 10px; margin-bottom: 6px; }
.hz-zone-head b { font-size: 1.05rem; flex: 1; }
.hz-zone-card p { margin: 0 0 6px; }
.hz-zone-time { display: flex; align-items: center; gap: 5px; font-weight: 800; color: var(--accent-text); }
.hz-zone-form { display: grid; grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr)); gap: 8px; margin-top: 10px; border-top: 1px solid var(--border); padding-top: 10px; }
.hz-zone-form .form-field { margin: 0; }
.hz-zone-form .hz-wide { grid-column: 1 / -1; }
.hz-zones { display: grid; grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr)); gap: 8px; margin-top: 10px; }
.hz-zone { display: flex; align-items: center; gap: 10px; text-align: left; background: var(--card); border: 1px solid var(--border); border-left: 4px solid var(--c); border-radius: var(--r-md); padding: 9px 10px; font: inherit; color: var(--ink); cursor: pointer; min-width: 0; }
.hz-zone:hover { background: var(--surface2); }
.hz-zone.on { background: var(--surface2); box-shadow: inset 0 0 0 1px var(--c); }
.hz-zone-main { display: flex; flex-direction: column; min-width: 0; flex: 1; }
.hz-zone-main b { font-size: .9rem; }
.hz-zone-main small { color: var(--muted); font-size: .75rem; }
.hz-zone-side { display: flex; flex-direction: column; align-items: flex-end; gap: 2px; flex: none; }
.hz-zone-side small { display: inline-flex; align-items: center; gap: 3px; font-weight: 800; color: var(--accent-text); font-size: .75rem; white-space: nowrap; }
.hz-euro { font-weight: 900; color: var(--ink); letter-spacing: .02em; font-size: .85rem; }
.hz-euro-off { color: var(--border); }
.hz-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr)); gap: 12px; align-items: start; margin-top: 8px; }
.hz-card { background: var(--card); border: 1px solid var(--border); border-radius: var(--r-md); padding: 12px 14px; min-width: 0; }
.hz-card h4 { margin: 0 0 8px; font-size: 1rem; font-weight: 900; }
.hz-card p { margin: 0 0 8px; line-height: 1.5; }
.hz-card ul { margin: 0 0 8px; padding-left: 18px; }
.hz-card li { margin-bottom: 4px; line-height: 1.45; }
.hz-links { display: flex; flex-direction: column; gap: 6px; margin: 4px 0 8px; }
.hz-link { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 9px 11px; border-radius: var(--r-sm); background: var(--surface2); color: var(--ink); text-decoration: none; min-width: 0; }
.hz-link:hover { background: var(--hover); text-decoration: none; }
.hz-link-main { display: flex; flex-direction: column; min-width: 0; }
.hz-link-main b { color: var(--accent-text); font-size: .9rem; }
.hz-link-main small { color: var(--muted); font-size: .8rem; line-height: 1.35; }
.hz-link-host { display: inline-flex; align-items: center; gap: 3px; font-size: .75rem; color: var(--muted); flex: none; white-space: nowrap; }
.hz-check { display: flex; gap: 10px; align-items: flex-start; padding: 7px 4px; border-bottom: 1px solid var(--border); cursor: pointer; line-height: 1.4; }
.hz-check:last-child { border-bottom: 0; }
.hz-check input { width: 18px; height: 18px; margin-top: 2px; flex: none; accent-color: var(--esn-green); }
.hz-check.done span { color: var(--muted); }
.hz-budget { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr); gap: 14px; align-items: start; }
.hz-budget-in label { font-weight: 700; font-size: .85rem; }
.hz-rent-row { display: flex; align-items: center; gap: 6px; margin: 6px 0 8px; font-size: 1.3rem; font-weight: 900; }
.hz-rent-row input { font-size: 1.15rem; font-weight: 800; width: 8rem; }
.hz-budget-out p { margin: 0 0 6px; }
.hz-verdict { display: flex; gap: 6px; align-items: flex-start; font-weight: 700; padding: 8px 10px; border-radius: var(--r-sm); background: var(--surface2); }
.hz-verdict.good { border-left: 4px solid var(--esn-green); }
.hz-verdict.mid { border-left: 4px solid var(--esn-cyan); }
.hz-verdict.warn { border-left: 4px solid var(--esn-orange); }
.hz-words ul { padding-left: 0; list-style: none; columns: 2 18rem; column-gap: 24px; }
.hz-words li { break-inside: avoid; margin-bottom: 8px; }
.hz-ask { display: flex; flex-direction: column; gap: 3px; text-decoration: none; color: var(--ink); }
.hz-ask:hover { background: var(--surface2); text-decoration: none; }
.hz-ask .material-symbols-rounded { color: var(--esn-cyan); font-size: 26px; }
.hz-ask small { color: var(--muted); }
.hz-places { margin-top: 12px; }
.hz-place-row { display: flex; align-items: center; gap: 8px; padding: 6px 0; border-bottom: 1px solid var(--border); }
.hz-place-row > span:nth-child(2) { display: flex; flex-direction: column; flex: 1; min-width: 0; }
.hz-place-row small { color: var(--muted); }
.hz-place-acts { display: inline-flex; gap: 2px; flex: none; }
@media (max-width: 640px) {
  .hz-hero { padding: 14px; }
  .hz-hero h2 { font-size: 1.45rem; }
  .hz-mapbox { height: 360px; }
  .hz-budget { grid-template-columns: minmax(0, 1fr); }
  .hz-nav { top: 52px; }
}
.office-grid { display: grid; grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr); gap: 20px; align-items: start; }
.office-facts { list-style: none; margin: 0 0 18px; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.office-facts li { display: flex; gap: 10px; align-items: flex-start; font-size: .9rem; }
.office-facts li .material-symbols-rounded { color: var(--esn-cyan); flex: 0 0 auto; margin-top: 1px; }
.office-tiles { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; margin-bottom: 8px; }
.office-tile { background: var(--card); border: 1px solid var(--border); border-radius: var(--r-md); padding: 12px; display: flex; flex-direction: column; gap: 4px; }
.office-tile .material-symbols-rounded { font-size: 24px; color: var(--esn-magenta); }
.office-tile strong { font-size: .95rem; }
.office-tile small { color: var(--muted); font-size: .8rem; line-height: 1.35; }
.office-map { margin-top: 0; position: sticky; top: 76px; }
@media (max-width: 760px) {
  .office-grid { grid-template-columns: minmax(0, 1fr); }
  .office-tiles { grid-template-columns: minmax(0, 1fr); }
  .office-map { position: static; }
}

/* ---------- The Ghent dragon loader (v0.138) ---------- */
.dragon-wrap { width: 132px; margin: 0 auto 10px; }
.dragon-wrap svg { width: 100%; height: auto; display: block; overflow: visible; }
/* 1.10.0: the facets are glass now. Each of the four tones is a gradient
   from ESN dark towards cyan, at a different angle per tone, so the low-poly
   dragon reads as lit from one side rather than flat-shaded. The stop colours
   live here, not in the SVG, so dark mode can re-tint them. Nothing was added
   to the SVG but four gradients, a clip and one rectangle: about 1.5 KB. */
.dragon .d1 { fill: url(#gd1); stroke: #3a4193; }
.dragon .d2 { fill: url(#gd2); stroke: #262b7a; }
.dragon .d3 { fill: url(#gd3); stroke: #7d84c9; }
.dragon .d4 { fill: url(#gd4); stroke: #20214f; }
.dragon .gs-1a { stop-color: #4d58b4; }
.dragon .gs-1b { stop-color: var(--esn-dark); }
.dragon .gs-2a { stop-color: var(--esn-dark); }
.dragon .gs-2b { stop-color: #1b7fc4; }
.dragon .gs-3a { stop-color: #b8c4f2; }
.dragon .gs-3b { stop-color: #59b9ec; }
.dragon .gs-4a { stop-color: #262a6d; }
.dragon .gs-4b { stop-color: #141642; }
html[data-theme="dark"] .dragon .d1 { stroke: #7f88d6; }
html[data-theme="dark"] .dragon .d2 { stroke: #5d64bd; }
html[data-theme="dark"] .dragon .d3 { stroke: #b9b7e6; }
html[data-theme="dark"] .dragon .d4 { stroke: #4a4f96; }
html[data-theme="dark"] .dragon .gs-1a { stop-color: #8a93e6; }
html[data-theme="dark"] .dragon .gs-1b { stop-color: #5860c4; }
html[data-theme="dark"] .dragon .gs-2a { stop-color: #5d64bd; }
html[data-theme="dark"] .dragon .gs-2b { stop-color: #33a9e8; }
html[data-theme="dark"] .dragon .gs-3a { stop-color: #e2e6ff; }
html[data-theme="dark"] .dragon .gs-3b { stop-color: #8fd4f7; }
html[data-theme="dark"] .dragon .gs-4a { stop-color: #4a4f96; }
html[data-theme="dark"] .dragon .gs-4b { stop-color: #2c2f6e; }
.dragon path { stroke-width: 1.6; stroke-linejoin: round; }
/* A band of light sweeps across the facets every few seconds, clipped to
   the dragon so it never spills. Screen blending keeps it a highlight. */
.dragon .gnt-sheen { mix-blend-mode: screen; opacity: .7; animation: gnt-sheen 3.6s cubic-bezier(.4, 0, .2, 1) infinite; }
/* The ground shadow shrinks as the dragon lifts, which is what sells the
   float: without it the dragon just slides up and down. */
.dragon .gnt-shadow { fill: #000; opacity: .16; transform-box: fill-box; transform-origin: center; animation: gnt-shadow 4.8s ease-in-out infinite alternate; }
html[data-theme="dark"] .dragon .gnt-shadow { fill: #000; opacity: .45; }
.dragon .gnt-float { animation: gnt-float 4.8s ease-in-out infinite alternate; }
.dragon .gnt-breathe { transform-box: fill-box; transform-origin: center; animation: gnt-breathe 6.4s ease-in-out infinite alternate; }
/* Embers, not smoke (1.10.0): the three puffs from the snout glow in the
   ESN colours, with a drop-shadow doing the glow so no filter primitive is
   needed. Sizes and paths are unchanged; only the paint. */
.dragon .puff { fill: var(--esn-orange); opacity: 0; transform-box: fill-box; transform-origin: center; animation: gnt-puff 5.4s linear infinite; filter: drop-shadow(0 0 28px var(--esn-orange)); }
.dragon .puff.p1 { fill: var(--esn-magenta); filter: drop-shadow(0 0 28px var(--esn-magenta)); }
.dragon .puff.p2 { fill: var(--esn-cyan); filter: drop-shadow(0 0 28px var(--esn-cyan)); }
.dragon .p1 { animation-name: gnt-puff2; }
.dragon .p2 { animation-name: gnt-puff3; }
@media (prefers-reduced-motion: reduce) {
  .dragon .gnt-float, .dragon .gnt-breathe, .dragon .puff, .dragon .gnt-sheen, .dragon .gnt-shadow { animation: none; }
  .dragon .puff { opacity: 0; }
  .dragon .gnt-sheen { opacity: 0; }
}

/* ---- ESNcard application: attachment + optional block (v1.1.0) ---- */
.attach-box { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; padding: 10px 12px; border: 1px dashed var(--border); border-radius: 10px; background: var(--surface2); }
.attach-name { font-size: .9rem; color: var(--ink); overflow-wrap: anywhere; }
.form-optional summary { list-style: none; display: inline-flex; align-items: center; gap: 6px; }
.form-optional summary::before { content: "▸"; font-size: .8em; transition: transform .15s ease; }
.form-optional[open] summary::before { transform: rotate(90deg); }
.form-optional summary::-webkit-details-marker { display: none; }
.form-field .chip-check, .chip-check { display: inline-flex; align-items: center; gap: 6px; padding: 5px 10px; border: 1px solid var(--border); border-radius: 999px; background: var(--card); font-size: .85rem; text-transform: none; letter-spacing: 0; color: var(--ink); cursor: pointer; }
.chip-check:has(input:checked) { border-color: var(--esn-dark); background: color-mix(in srgb, var(--esn-dark) 10%, var(--card)); }
.chip-check input { width: 15px; height: 15px; accent-color: var(--esn-dark); margin: 0; }

/* ---- Admin: application review (v1.1.0) ---- */
.assign-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.app-full { margin: 0; }
.app-detail-row td { padding-top: 0 !important; border-top: 0 !important; }
.app-full summary { list-style: none; display: inline-flex; align-items: center; gap: 4px; }
.app-full summary::-webkit-details-marker { display: none; }
.sub-grid { display: grid; grid-template-columns: max-content 1fr; gap: 3px 12px; margin-top: 8px; padding: 10px 12px; border-radius: 10px; background: var(--surface2); font-size: .85rem; max-width: 520px; }
.sub-grid .sub-row { display: contents; }
.sub-grid .sub-k { color: var(--muted); white-space: nowrap; }
.sub-grid .sub-v { color: var(--ink); overflow-wrap: anywhere; }
@media (max-width: 640px) {
  .sub-grid { grid-template-columns: minmax(0, 1fr); max-width: none; }
  .sub-grid .sub-k { margin-top: 6px; }
}

/* 1.34.0: Tally. The form strip on a ticket, the applications queue, the Settings card. */
.apps-list { display: flex; flex-direction: column; gap: 6px; }
.app-row { border: 1px solid var(--border); border-radius: 10px; padding: 0; }
.app-row summary { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; padding: 10px 12px; cursor: pointer; }
.app-row[open] summary { border-bottom: 1px solid var(--border); }
.app-body { padding: 10px 12px 12px; }
.app-answers { white-space: pre-wrap; font: inherit; font-size: .85rem; margin: 0 0 8px; padding: 10px 12px; background: var(--surface2); border-radius: var(--r-sm); max-height: 320px; overflow: auto; }
.tally-status { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.tally-status code, #tally-url { font-size: .8rem; }
.app-state { padding: 7px 10px; border: 1px solid var(--border); border-radius: var(--r-sm); font: inherit; font-size: .85rem; background: var(--card); color: var(--ink); }
/* The brand word inside an uppercase parent (1.34.2): ESNcard stays ESNcard. */
/* Form answers (1.34.0): one column per question; long answers wrap, the
   table scrolls sideways, on a phone every row is a card. */
.ans-wrap table { min-width: 100%; }
.ans-cell { max-width: 280px; min-width: 120px; white-space: pre-wrap; overflow-wrap: anywhere; font-size: .85rem; vertical-align: top; }
.ans-earlier { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.ans-earlier .app-answers { margin: 4px 0 0; }
.ans-todo { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 6px 14px; }
.ans-todo li { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; min-height: 32px; }
.ans-todo li small { overflow-wrap: anywhere; }

/* ---- ESNcard form v1.2.0: stay period, "Other" free text ---- */
.month-row { display: grid; grid-template-columns: 1fr 96px; gap: 8px; }
.other-input { margin-top: 8px; }

/* ---- Admin overview donuts (v1.2.0) ---- */
.apps-overview summary { list-style: none; cursor: pointer; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.apps-overview summary::-webkit-details-marker { display: none; }
.donut-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 14px; margin-top: 14px; }
.donut { border: 1px solid var(--border); border-radius: 10px; padding: 12px 14px; background: var(--surface2); min-width: 0; }
.donut h4 { margin: 0 0 8px; font-size: .8rem; text-transform: uppercase; letter-spacing: .5px; color: var(--muted); }
.donut-body { display: flex; align-items: center; gap: 14px; }
.donut svg { width: 112px; height: 112px; flex: none; }
.donut svg circle { transition: opacity var(--t-fast) ease; }
.donut svg:hover circle:not(:hover):not(:first-child) { opacity: .45; }
.donut-num { font-size: 20px; font-weight: 700; fill: var(--ink); }
.donut-cap { font-size: 8px; fill: var(--muted); text-transform: uppercase; letter-spacing: .8px; }
.donut-legend { list-style: none; margin: 0; padding: 0; flex: 1; min-width: 0; font-size: .8rem; }
.donut-legend li { display: grid; grid-template-columns: 10px 1fr auto auto; gap: 8px; align-items: start; padding: 3px 0; }
.donut-legend .sw { width: 10px; height: 10px; border-radius: 3px; margin-top: 3px; }
.donut-legend .lb { color: var(--ink); overflow-wrap: anywhere; line-height: 1.25; }
.donut-legend .ct { color: var(--ink); font-weight: 600; font-variant-numeric: tabular-nums; }
.donut-legend .pc { color: var(--muted); font-variant-numeric: tabular-nums; min-width: 34px; text-align: right; }

/* ---- Users tab (v1.3.0): dropdown filters, institution chips, team rows ---- */
/* An institution chip is capped in width everywhere (the full text is the
   tooltip), so one long typed-in name cannot widen the Student column and
   push the assign buttons off the screen. */
.inst-chip { display: inline-block; padding: 3px 9px; border-radius: 999px; font-size: .8rem; font-weight: 600; line-height: 1.3; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; vertical-align: middle; max-width: min(100%, 260px); }
tr.row-team > td:first-child { box-shadow: inset 3px 0 0 var(--esn-dark); }

/* ---- ESNcard work queue (v1.4.0): dense rows, sticky filters, desk flow ---- */
.queue-sticky { position: sticky; top: var(--hdr, 0px); z-index: 5; background: var(--bg); padding: 8px 0 6px; margin: 0 0 6px; }
.table-wrap.queue td { padding: 8px 10px; vertical-align: middle; }
/* the phone card cell (1.40.0) */
.table-wrap.queue .badge { white-space: nowrap; }
.td-stack { min-width: 0; }
.table-wrap.queue .assign-row .inline-input { height: 34px; }
.table-wrap.queue tr[hidden] { display: none; }
/* The ESNcard queue fits a laptop without a sideways scroll: the actions
   column wraps into two rows (number and scan, then assign and reject). */
.table-wrap.queue td.queue-actions { min-width: 240px; white-space: normal; }  /* 1.15.0: colours per category */
.table-wrap.queue .assign-row { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.table-wrap.queue .assign-row .app-cardnum { flex: 1 1 120px; min-width: 120px; width: auto; }
.table-wrap.queue td[data-l="Student"] .td-stack { min-width: 150px; max-width: 300px; overflow-wrap: anywhere; white-space: normal; }
.table-wrap.queue td[data-l="Applied"] { white-space: normal !important; }
/* 1.52.0: the queue on a phone. It was four grey boxes per student with the
   labels left and the values pushed right; now one card that reads top to
   bottom: name and status, who they are, when and the proof, the desk
   action. A paid row is marked by its green edge, not by tinted cells. */
.queue-tools { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin: 0 0 10px; }
.queue-tools #apps-count { margin-right: auto; }
.queue-tools .fsel .year-picker { border: 0; background: transparent; height: auto; min-height: 0; padding: 7px 26px 7px 2px; box-shadow: none; }
.q-who { display: block; margin-top: 3px; }
@media (max-width: 820px) {
  .table-wrap.queue tr[data-uid]:not(.app-detail-row) {
    display: grid; grid-template-columns: minmax(0, 1fr) fit-content(58%); column-gap: 12px; row-gap: 6px;  /* 1.77.6: the status cell wraps at 58 percent instead of squeezing the name to one letter a line */
    grid-template-areas: "main status" "who who" "when proof" "act act";
  }
  .table-wrap.queue tr.row-hot { box-shadow: var(--shadow), inset 4px 0 0 var(--esn-green); }
  .table-wrap.queue tr.row-hot td { background: none; }
  .table-wrap.queue td { padding: 0; }
  .table-wrap.queue td.card-main { grid-area: main; border: 0; margin: 0; padding: 0; min-width: 0; overflow-wrap: anywhere; }
  .table-wrap.queue td.card-main .btn-link { margin-top: 0; min-height: 28px; }
  .table-wrap.queue td[data-l="Status"] { grid-area: status; align-items: flex-end; text-align: right; }
  .table-wrap.queue td[data-l="Student"] { grid-area: who; padding: 8px 0 0; border-top: 1px dashed var(--border); }
  .table-wrap.queue td[data-l="Applied"] { grid-area: when; flex-direction: row; align-items: baseline; justify-content: flex-start; gap: 6px; }
  .table-wrap.queue td[data-l="Applied"] .td-stack { text-align: left; }
  .table-wrap.queue td[data-l="Proof"] { grid-area: proof; flex-direction: row; align-items: center; justify-content: flex-end; gap: 6px; }
  .table-wrap.queue td[data-l="Student"]::before, .table-wrap.queue td[data-l="Status"]::before { display: none; }
  .table-wrap.queue td[data-l="Student"] .td-stack { max-width: none; min-width: 0; text-align: left; }
  .table-wrap.queue td.queue-actions { grid-area: act; min-width: 0; padding-top: 4px; }
  .table-wrap.queue td.queue-actions:empty { display: none; }
  .table-wrap.queue .assign-row .app-cardnum { flex: 1 1 100%; min-width: 0; height: 44px; font-size: 1rem; }
  .table-wrap.queue .assign-row .btn { flex: 1 1 auto; min-height: 40px; justify-content: center; }
  .table-wrap.queue .assign-row .app-scan { flex: 0 0 48px; }
}
@media (max-width: 640px) {
  .queue-sticky { position: static; }
  .cards td .td-stack { text-align: right; overflow-wrap: anywhere; white-space: normal; }
}

/* ---- v1.5.0 audit: map theming, status dots, news feed, touch targets ---- */
.status-dot { display: inline-block; width: 9px; height: 9px; border-radius: 50%; margin-right: 6px; vertical-align: 0; }
.news-grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: 16px; }
.news-cover { width: 100%; aspect-ratio: 16 / 9; object-fit: cover; display: block; }
.news-body { padding: 18px 20px 20px; }
.news-meta { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; margin: 0 0 6px; font-size: .8rem; color: var(--muted); }
.news-title { margin: 0 0 8px; font-size: 1.15rem; line-height: 1.3; }
@media (min-width: 821px) {
  .news-grid { grid-template-columns: 1fr 1fr; align-items: start; }
  .news-card.news-latest .news-cover { width: 42%; aspect-ratio: auto; height: 300px; align-self: stretch; }
  .news-card.news-latest .news-body { flex: 1; padding: 24px 26px; }
  .news-card.news-latest .news-title { font-size: 1.45rem; }
}

/* ---------- Home: this-week strip (v1.1.6) ---------- */
/* Home: this-week strip */
.week-strip { display: flex; align-items: center; gap: 10px; margin: 6px 0 -6px; }
.week-label { flex: none; font-size: .75rem; font-weight: 800; text-transform: uppercase; letter-spacing: .5px; color: var(--muted); display: inline-flex; align-items: center; gap: 4px; }
.week-scroll { display: flex; gap: 8px; overflow-x: auto; scrollbar-width: none; padding: 4px 0; min-width: 0; }
.week-scroll::-webkit-scrollbar { display: none; }
.week-chip { flex: none; display: flex; flex-direction: column; gap: 1px; padding: 6px 12px; border: 1px solid var(--border); border-left: 4px solid var(--wc, var(--esn-cyan)); border-radius: 10px; background: var(--card); color: var(--ink); text-decoration: none; max-width: 210px; }
.week-chip small { font-size: .75rem; color: var(--muted); }
.week-chip strong { font-size: .8rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.week-chip:hover { text-decoration: none; border-color: var(--esn-cyan); }
@media (max-width: 640px) {
  .week-strip { flex-direction: column; align-items: flex-start; gap: 4px; }
  .week-scroll { width: 100%; }
}

/* ---- 1.1.7: home "Good to know" tiles + calm empty state ---- */
.home-empty { display: block; margin: 4px 0 8px; padding: 14px 16px; border: 1px dashed var(--border); border-radius: var(--r-md); color: var(--muted); font-size: .9rem; line-height: 1.5; }
.home-empty .material-symbols-rounded { vertical-align: -4px; margin-right: 6px; }
.home-grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: 12px; margin-bottom: 8px; }
.home-tile, .home-tile-link { display: flex; align-items: center; gap: 14px; padding: 14px 16px; background: var(--card); border: 1px solid var(--border); border-radius: var(--r-md); box-shadow: var(--shadow); color: var(--ink); text-decoration: none; min-height: 84px; }
.home-tile:hover, .home-tile-link:hover { text-decoration: none; border-color: var(--esn-cyan); }
.home-tile-icon { flex: none; width: 42px; height: 42px; border-radius: var(--r-md); display: flex; align-items: center; justify-content: center; background: color-mix(in srgb, var(--tc, var(--esn-cyan)) 14%, var(--card)); color: var(--tc, var(--esn-cyan)); }
.home-tile-icon .material-symbols-rounded { font-size: 24px; }
.home-tile-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.home-tile-main small { font-size: .75rem; color: var(--muted); text-transform: uppercase; letter-spacing: .4px; font-weight: 700; }
.home-tile-main strong { font-size: .95rem; line-height: 1.3; overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
.home-tile .chev { color: var(--muted); font-size: 1.15rem; }
.home-tile-deal { padding: 0; border: 0; box-shadow: none; background: none; min-height: 0; }
.home-tile-deal .home-tile-link { width: 100%; }
.home-tile-deal .deal-logo { width: 42px; height: 42px; border-radius: 10px; flex: none; object-fit: cover; }
.home-tile { border-radius: var(--radius); }  /* 1.29.4: colour follow-ups */
@media (min-width: 821px) {
  .home-grid { grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }
  .home-grid:has(> :nth-child(4):last-child) { grid-template-columns: repeat(2, minmax(0, 1fr)); }  /* 1.78.9: four cards two by two, none alone on a row */
}

/* ---- 1.18.1: the passport on the home screen ----
   A small echo of the passport cover, so the streak and the season count
   are seen without being looked for. Same dark cover, one stamp disc, the
   level colour as the accent. */
.pp-strip {
  display: flex; align-items: center; gap: 14px;
  background: linear-gradient(160deg, #232668, var(--esn-dark) 62%, #171a4a);   /* the cover gradient, the blue a little wider */
  border: 1px solid rgba(255, 255, 255, .12); border-radius: var(--r-lg);
  padding: 12px 14px; margin: 0 0 18px; text-decoration: none; color: #fff;
  box-shadow: 0 6px 18px rgba(30, 32, 90, .18);
}
.pp-strip:hover { text-decoration: none; filter: brightness(1.08); }
.pp-strip-stamp {
  flex: 0 0 56px; width: 56px; height: 56px; border-radius: 50%;
  display: flex; flex-direction: column; align-items: center; justify-content: center; line-height: 1;
  border: 2px dashed var(--lvl, var(--esn-cyan)); background: rgba(255, 255, 255, .07); color: #fff;
  transform: rotate(-7deg);
}
.pp-strip-stamp strong { font-size: 1.3rem; font-weight: 900; }
.pp-strip-stamp small { font-size: .75rem; letter-spacing: .5px; text-transform: uppercase; opacity: .8; margin-top: 2px; }
.pp-strip-hint { font-size: .8rem; color: rgba(255, 255, 255, .78); }
.pp-strip-chev { color: rgba(255, 255, 255, .55); font-size: 1.45rem; line-height: 1; flex: none; }
.pp-strip.at-risk .pp-strip-stamp { border-style: solid; border-color: var(--esn-orange); }
.pp-strip.at-risk .pp-strip-hint { color: #ffd9b8; }
/* 1.78.7: the home spotlight (spotlight.js): the passport strip's card, with a different moment each visit */
.spot { position: relative; margin: 0 0 18px; }
.spot .pp-strip { margin: 0; padding-right: 58px; }
.spot-wait { min-height: 82px; border-radius: var(--r-lg); background: linear-gradient(160deg, #232668, var(--esn-dark) 62%, #171a4a); opacity: .55; }
.spot-ic, .spot-lvl, .spot-wx { flex: 0 0 56px; width: 56px; height: 56px; border-radius: 50%; display: flex; flex-direction: column; align-items: center; justify-content: center; line-height: 1; color: #fff; background: color-mix(in srgb, var(--lvl, var(--esn-cyan)) 24%, transparent); box-shadow: inset 0 0 0 2px color-mix(in srgb, var(--lvl, var(--esn-cyan)) 70%, transparent); }
.spot-ic .material-symbols-rounded { font-size: 28px; color: var(--lvl, var(--esn-cyan)); }
.spot-lvl strong { font-size: 1.3rem; font-weight: 900; }
.spot-lvl small { font-size: .7rem; letter-spacing: .5px; text-transform: uppercase; opacity: .8; margin-top: 2px; }
.spot-wx .material-symbols-rounded { font-size: 22px; }
.spot-wx strong { font-size: 1.05rem; font-weight: 900; margin-top: 1px; }
.spot-bar { display: block; height: 6px; margin-top: 6px; border-radius: 999px; background: rgba(255, 255, 255, .14); overflow: hidden; }
.spot-bar i { display: block; width: var(--w); height: 100%; border-radius: inherit; background: var(--lvl, var(--esn-cyan)); transform-origin: left center; }
.spot-next { position: absolute; top: 50%; right: 12px; transform: translateY(-50%); display: grid; place-items: center; width: 36px; height: 36px; padding: 0; border: 1px solid rgba(255, 255, 255, .28); border-radius: 50%; background: rgba(255, 255, 255, .08); color: #fff; cursor: pointer; }
.spot-next:hover { background: rgba(255, 255, 255, .18); }
.spot-next .material-symbols-rounded { font-size: 20px; }
@keyframes spot-in { from { opacity: 0; transform: translateY(8px) scale(.98); } }
@keyframes spot-disc { from { opacity: 0; transform: scale(.5) rotate(-25deg); } }
@keyframes spot-bar { from { transform: scaleX(0); } }
@keyframes spot-spin { to { transform: rotate(360deg); } }
@keyframes spot-glow { 0%, 100% { box-shadow: inset 0 0 0 2px var(--lvl), 0 0 0 0 color-mix(in srgb, var(--lvl) 55%, transparent); } 50% { box-shadow: inset 0 0 0 2px var(--lvl), 0 0 0 10px transparent; } }
@media (prefers-reduced-motion: no-preference) {
  .spot-in .pp-strip { animation: spot-in .45s cubic-bezier(.2, .7, .3, 1) both; }
  .spot-in .spot-ic, .spot-in .spot-lvl, .spot-in .spot-wx, .spot-in .pp-strip-stamp { animation: spot-disc .55s .08s cubic-bezier(.2, .7, .3, 1.5) both; }
  .spot-in .spot-bar i { animation: spot-bar .9s .25s cubic-bezier(.2, .7, .3, 1) both; }
  .spot-pop .spot-ic { animation: spot-disc .55s .08s cubic-bezier(.2, .7, .3, 1.5) both, spot-glow 1.6s .7s ease-out 2; }
  .spot-next.spin .material-symbols-rounded { animation: spot-spin .7s linear infinite; }
}
@media (max-width: 420px) {
  .pp-strip { gap: 11px; padding: 11px 12px; }
  .pp-strip-stamp { flex: 0 0 48px; width: 48px; height: 48px; }
  .pp-strip-stamp strong { font-size: 1.15rem; }
}

/* ---- 1.1.7: passport structure + denser stamps ---- */
.pp-h { display: flex; align-items: center; gap: 6px; margin: 22px 0 10px; font-size: .8rem; font-weight: 800; text-transform: uppercase; letter-spacing: .6px; color: var(--muted); }
.pp-h .form-hint { text-transform: none; letter-spacing: 0; font-weight: 500; }
.pp-month-block { margin-bottom: 6px; }
.pp-month-head { display: flex; justify-content: space-between; align-items: baseline; margin: 0 2px 8px; }
.pp-month-head strong { font-size: .95rem; }
.pp-archive .pp-month-block { margin-top: 12px; }

/* ============================================================
   ESN Passport motion (1.7.0)
   ============================================================
   The passport is the page students show each other, so it is the one place
   in the app that earns a bit of theatre. Everything here animates transform
   and opacity only, so it runs on the compositor and costs a phone nothing,
   and every rule below is switched off wholesale by the global
   prefers-reduced-motion reset further up this file.
   Timings are deliberately on one curve: cubic-bezier(.22,1,.36,1), which
   arrives fast and settles slowly. It is what makes a thing feel light
   rather than sluggish. */
/* XP towards the next level, as a bar. The number alone ("43 XP to Regular")
   never told anybody whether that was nearly there or nowhere near. */
.pp-xp-bar {
  display: block; height: 7px; max-width: 240px; margin-top: 8px;
  border-radius: 999px; background: rgba(255, 255, 255, .16);
  overflow: hidden; position: relative;
}
.pp-xp-bar i {
  /* Same reasoning as the ring: rest at the real width, animate up from zero. */
  display: block; height: 100%; width: 100%; border-radius: 999px;
  transform: translateX(calc(var(--pp-fill, 0%) - 100%)); /* 1.69.5: moved, not resized: no layout per frame */
  background: linear-gradient(90deg, var(--esn-cyan), var(--esn-green));
  box-shadow: 0 0 12px rgba(122, 193, 67, .55);
  animation: pp-xp-fill 1.15s .3s cubic-bezier(.22, 1, .36, 1) both;
}
/* One slow glint travelling along the filled part, so a full-ish bar still
   reads as alive on a page somebody is showing to a friend. */
.pp-xp-bar::after {
  content: ""; position: absolute; inset: 0; border-radius: 999px;
  background: linear-gradient(100deg, transparent 35%, rgba(255, 255, 255, .45) 50%, transparent 65%);
  transform: translateX(-100%);
  animation: pp-glint 3.4s 1.5s ease-in-out infinite;
}
/* Collections: a bar under each row, so "3/14" has a shape as well as a number. */
.pp-count-bar {
  /* flex-basis 100% drops it onto its own line inside the flex summary it
     lives in, so the bar spans the row under the title rather than squeezing
     in beside it. */
  flex: 0 0 100%;
  display: block; height: 5px; border-radius: 999px; margin-top: 2px;
  background: rgba(128, 128, 160, .22); overflow: hidden;
}
.pp-count-bar i {
  display: block; height: 100%; width: 100%; border-radius: 999px;
  transform: translateX(calc(var(--pp-fill, 0%) - 100%));
  background: linear-gradient(90deg, var(--esn-cyan), var(--esn-magenta));
  animation: pp-xp-fill 1s .4s cubic-bezier(.22, 1, .36, 1) both;
}

/* ---- 1.17.0: ESN Passport 2.0 ---- */
/* The stamp moment: the screen right after the door scan. */
.stamp-moment { position: relative; min-height: calc(100vh - 140px); display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 16px; padding: 28px 18px 32px; margin: -10px -16px 0; text-align: center; color: #fff; background: radial-gradient(circle at 50% 36%, #2b2f8f 0%, #1a1d5e 45%, #0f1136 100%); overflow: hidden; }
.stamp-moment h1 { margin: 0; font-size: 1.7rem; font-weight: 900; }
.sm-scan { position: absolute; top: 14px; right: 16px; margin: 0; font-size: .75rem; color: #9fd9f6; }
.sm-rays { position: absolute; width: 360px; height: 360px; top: 60px; border-radius: 50%; background: radial-gradient(circle, rgba(0,174,239,.35) 0%, rgba(0,174,239,0) 68%); pointer-events: none; }
.sm-stamp { position: relative; width: 210px; height: 210px; border-radius: 50%; border: 6px double var(--stamp); color: var(--stamp); display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px; background: rgba(255,255,255,.04); box-shadow: 0 0 0 14px color-mix(in srgb, var(--stamp) 16%, transparent), 0 30px 60px rgba(0,0,0,.45); transform: rotate(-7deg) scale(1); }
.sm-stamp.is-gold { color: #ffd75e; border-color: #EAB308; }
.sm-stamp .sm-ico .material-symbols-rounded { font-size: 56px; }
.sm-stamp b { font-size: 1.15rem; letter-spacing: 2px; }
.sm-stamp .sm-title { font-size: .8rem; font-weight: 900; letter-spacing: 1px; padding: 0 16px; }
.sm-stamp small { font-size: .75rem; color: #c9cbe6; }
.sm-sub { margin: 0; color: #c9cbe6; font-size: .95rem; }
.sm-level { width: 100%; max-width: 360px; display: flex; flex-direction: column; gap: 6px; }
.sm-level-row { display: flex; justify-content: space-between; font-size: .8rem; color: #c9cbe6; }
.sm-actions { display: flex; gap: 10px; flex-wrap: wrap; justify-content: center; }
/* 1.50.1: "ESNcard" keeps its spelling inside labels set in capitals (see keepEsncardCase) */
.esncard-word { text-transform: none; }
.sm-actions .btn-on-dark { color: #fff; border-color: rgba(255, 255, 255, .35); }
.sm-hint { margin: 0; font-size: .75rem; color: #9a9cb5; }
/* 1.69.3: the stamp moment without a card is short: the passport explainer follows it */
.stamp-moment.sm-short { min-height: 0; padding-bottom: 26px; margin-bottom: 18px; }
/* ---------- The passport, locked (1.69.3): what is behind the door, with
   the person's own stamps counted; the card is the key ---------- */
.pp-locked { max-width: 560px; margin: 0 auto; }
.ppl-card { position: relative; overflow: hidden; border-radius: var(--radius); padding: 18px 18px 16px; color: #fff; background: radial-gradient(circle at 20% 0%, #2b2f8f 0%, #1a1d5e 55%, #0f1136 100%); box-shadow: var(--shadow-lg); animation: ppl-in .5s cubic-bezier(.2, .7, .3, 1) both; }
.ppl-head { display: flex; align-items: center; gap: 14px; margin-bottom: 14px; }
.ppl-lock { flex: none; width: 48px; height: 48px; border-radius: 50%; display: flex; align-items: center; justify-content: center; background: rgba(255, 255, 255, .1); border: 1px solid rgba(255, 255, 255, .22); animation: ppl-wiggle .7s ease 1.1s 1; }
.ppl-lock .material-symbols-rounded { font-size: 26px; color: #ffd75e; }
.ppl-title { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.ppl-title strong { font-size: 1.15rem; font-weight: 900; }
.ppl-title small { font-size: .85rem; color: #c9cbe6; }
.ppl-title b { color: #fff; font-size: 1rem; }
.ppl-hexes { display: flex; justify-content: space-between; gap: 6px; margin: 0 0 14px; }
.ppl-hex { display: flex; flex-direction: column; align-items: center; gap: 4px; flex: 1; animation: pp-tile-in .5s cubic-bezier(.22, 1, .36, 1) both; animation-delay: calc(.35s + var(--i, 0) * .09s); }
.ppl-hex small { font-size: .75rem; color: #c9cbe6; }
.ppl-hex .pp-hex-bg { background: rgba(255, 255, 255, .12); }
.ppl-hex .pp-hex.locked .pp-badge-icon .material-symbols-rounded { color: #9fd9f6; opacity: .9; }
.ppl-track { display: flex; flex-direction: column; gap: 6px; }
.ppl-track .pp-xp-bar { background: rgba(255, 255, 255, .12); max-width: none; margin-top: 0; }
.ppl-track .pp-xp-bar i { animation: pp-xp-fill 1s cubic-bezier(.2, .7, .3, 1) .8s both; }
.ppl-track small { font-size: .75rem; color: #9a9cb5; }
.ppl-rows { list-style: none; padding: 0; margin: 16px 0 10px; display: flex; flex-direction: column; gap: 10px; }
.ppl-rows li { display: flex; gap: 12px; align-items: flex-start; font-size: .95rem; line-height: 1.45; animation: settleIn .35s ease both; animation-delay: calc(.25s + var(--i, 0) * .06s); }
.ppl-rows .material-symbols-rounded { flex: none; margin-top: 2px; color: var(--esn-cyan); }
.ppl-key { display: flex; gap: 10px; align-items: flex-start; margin: 0 0 14px; padding: 12px 14px; border-radius: var(--r-md); background: color-mix(in srgb, var(--esn-magenta) 10%, var(--card)); border: 1px solid color-mix(in srgb, var(--esn-magenta) 35%, var(--border)); font-size: .9rem; line-height: 1.45; }
.ppl-key .material-symbols-rounded { flex: none; color: var(--esn-magenta); margin-top: 2px; }
.ppl-actions { justify-content: center; margin: 0 0 10px; }
.ppl-have { text-align: center; margin: 0; }
@keyframes ppl-in { from { opacity: 0; transform: translateY(14px) scale(.98); } to { opacity: 1; transform: none; } }
@keyframes ppl-wiggle { 0%, 100% { transform: rotate(0); } 20% { transform: rotate(-12deg); } 45% { transform: rotate(10deg); } 70% { transform: rotate(-5deg); } }
/* Cover: streak, rank, the gold season skin. */
.pp-rank { display: block; font-size: .75rem; color: #9fd9f6; margin-top: 4px; }
.pp-streak { display: flex; align-items: center; gap: 8px; border-radius: var(--r-md); background: rgba(255,255,255,.1); font-size: .8rem; color: #c9cbe6; margin: 12px 0 12px; padding: 9px 12px; }
.pp-streak strong { color: #fff; white-space: nowrap; }
.pp-streak.on .material-symbols-rounded { color: var(--esn-orange); }
.pp-streak.risk { background: rgba(244,123,32,.18); }
/* Quests and the next badge. */
.pp-quests { margin: 0 0 12px; border-radius: var(--radius); }
.pp-quests-head { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 8px; }
.pp-quest { display: flex; align-items: center; gap: 12px; padding: 8px 0; border-top: 1px solid var(--border); }
.pp-quest:first-of-type { border-top: 0; }
.pp-quest.done .pp-quest-ic .material-symbols-rounded { color: var(--esn-green); }
.pp-quest-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 5px; }
.pp-quest-title { font-size: .9rem; font-weight: 700; }
.pp-quest-bar { height: 6px; border-radius: 999px; background: var(--border); overflow: hidden; }
.pp-quest-bar i { display: block; height: 100%; background: var(--esn-cyan); width: 100%; transform: translateX(calc(var(--p, 0%) - 100%)); transition: transform .4s ease; }
.pp-quest.done .pp-quest-bar i { background: var(--esn-green); }
.pp-quest-xp { font-size: .8rem; font-weight: 900; color: var(--esn-dark); white-space: nowrap; padding: 4px 8px; border-radius: 999px; background: var(--hover); }
html[data-theme="dark"] .pp-quest-xp { color: var(--esn-cyan); }
.pp-next { display: flex; align-items: center; gap: 12px; margin: 0 0 14px; text-decoration: none; color: inherit; border-radius: var(--radius); }
.pp-next:hover { border-color: var(--esn-cyan); text-decoration: none; }
.pp-next-ic { width: 46px; height: 46px; border-radius: var(--r-md); background: var(--hover); display: flex; align-items: center; justify-content: center; flex: none; }
.pp-next-ic .material-symbols-rounded { font-size: 24px; color: var(--esn-magenta); }
.pp-next-main { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.pp-next-main small { color: var(--muted); font-size: .8rem; }
/* Badges: artwork, rarity. */
.pp-badge-art { width: 52px; height: 52px; object-fit: contain; display: block; margin: 0 auto; }
.pp-badge-art.locked { filter: grayscale(1) contrast(.6) brightness(1.1); opacity: .5; }
.pp-next-ic .pp-badge-art { width: 34px; height: 34px; }
.pp-badge-rar { font-size: .75rem; font-weight: 700; text-transform: uppercase; letter-spacing: .5px; color: var(--muted); }
.pp-badge.earned .pp-badge-rar { color: var(--ink); }
html[data-theme="dark"] .stamp-page { background: #2a2820; border-color: #3d3a2e; }
html[data-theme="dark"] .stamp-page .stamp { mix-blend-mode: normal; }
/* Season track. */
.pp-season-head { display: flex; justify-content: space-between; align-items: baseline; flex-wrap: wrap; gap: 6px; margin-bottom: 8px; }
.pp-track { display: flex; flex-direction: column; }
.pp-tier { display: flex; align-items: center; gap: 12px; padding: 9px 0; border-top: 1px solid var(--border); }
.pp-tier:not(.reached) { color: var(--muted); }  /* 1.77.0: a tier not yet reached is muted ink, not 60 percent opacity (its small text fell to 2.5:1) */
.pp-tier:first-child { border-top: 0; }
.pp-tier.reached { opacity: 1; }
.pp-tier-dot { width: 34px; height: 34px; border-radius: 50%; border: 3px solid var(--border); display: flex; align-items: center; justify-content: center; font-size: .8rem; font-weight: 900; color: var(--muted); flex: none; }
.pp-tier.reached .pp-tier-dot { background: var(--esn-green); border-color: var(--esn-green); color: var(--on-bright); }
.pp-tier-main { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.pp-tier-main small { color: var(--muted); font-size: .8rem; }
/* Friends. */
.pp-friend-row { display: flex; align-items: center; gap: 10px; padding: 8px 0; border-top: 1px solid var(--border); }
.pp-friend-row:first-child { border-top: 0; }
.pp-friend-row > span:first-child { flex: 1; min-width: 0; }
.pp-friend-lvl { width: 26px; height: 26px; border-radius: 50%; color: #fff; font-size: .75rem; font-weight: 900; display: flex; align-items: center; justify-content: center; flex: none; }
.pp-friend-reqs { margin-bottom: 8px; padding: 8px 10px; border-radius: 10px; background: var(--hover); }
.pp-quest.done .pp-quest-xp { color: var(--green-text); }  /* 1.17.1: passport polish */
.pp-quests-head strong, .pp-season-head strong { font-size: 1rem; font-weight: 800; }  /* 1.29.1: the passport */
.pp-quests-head strong .material-symbols-rounded { font-size: 16px; color: var(--esn-dark); }
html[data-theme="dark"] .pp-quests-head strong .material-symbols-rounded { color: var(--esn-cyan); }
@media (prefers-reduced-motion: no-preference) {
  .sm-stamp { animation: sm-slam .7s cubic-bezier(.2, 1.4, .4, 1) .25s both; }
  .stamp-moment h1 { animation: sm-rise .5s ease-out both; animation-delay: .6s; }
  .sm-sub { animation: sm-rise .5s ease-out both; animation-delay: .7s; }
  .sm-level { animation: sm-rise .5s ease-out both; animation-delay: .85s; }
  .sm-actions { animation: sm-rise .5s ease-out both; animation-delay: 1s; }
  .sm-hint { animation: sm-rise .5s ease-out both; animation-delay: 1.15s; }
}

/* ---- 1.17.1: passport polish ---- */
.pp-quest-ic .material-symbols-rounded { color: var(--esn-dark); font-size: 24px; }  /* 1.17.0: ESN Passport 2.0 */
html[data-theme="dark"] .pp-quest-ic .material-symbols-rounded { color: var(--esn-cyan); }
.pp-cover-glow { position: absolute; right: -40px; top: 30px; width: 260px; height: 260px; border-radius: 50%; background: radial-gradient(circle, rgba(0, 174, 239, .35) 0%, rgba(0, 174, 239, 0) 70%); pointer-events: none; }
.pp-cover.pp-gold .pp-cover-glow { background: radial-gradient(circle, rgba(255, 215, 94, .35) 0%, rgba(255, 215, 94, 0) 70%); }
.pp-quest-ic { width: 40px; height: 40px; border-radius: var(--r-md); background: var(--hover); display: flex; align-items: center; justify-content: center; flex: none; }
/* Hexagon badge frames: the frame fills from the bottom as you get closer. */
.pp-hex { position: relative; width: 72px; height: 72px; margin: 0 auto 4px; display: block; }
.pp-hex.sm { width: 52px; height: 52px; margin: 0; flex: none; }
.pp-hex-bg { position: absolute; inset: 0; clip-path: polygon(50% 2%, 94% 26%, 94% 74%, 50% 98%, 6% 74%, 6% 26%); background: var(--border); }
.pp-hex-fill { position: absolute; inset: 0; background: var(--esn-cyan); clip-path: polygon(50% 2%, 94% 26%, 94% 74%, 50% 98%, 6% 74%, 6% 26%); -webkit-mask: linear-gradient(to top, #000 var(--fill, 0%), transparent var(--fill, 0%)); mask: linear-gradient(to top, #000 var(--fill, 0%), transparent var(--fill, 0%)); }
.pp-hex.got .pp-hex-fill { background: var(--esn-green); }
.pp-badge.rar-rare .pp-hex.got .pp-hex-fill { background: var(--esn-cyan); }
.pp-badge.rar-epic .pp-hex.got .pp-hex-fill { background: var(--esn-magenta); }
.pp-badge.rar-legendary .pp-hex.got .pp-hex-fill { background: #EAB308; }
.pp-hex .pp-badge-icon { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; }
.pp-hex.got .pp-badge-icon .material-symbols-rounded { color: #fff; font-size: 32px; }
.pp-hex.locked .pp-badge-icon .material-symbols-rounded { color: var(--muted); opacity: .75; font-size: 28px; }
.pp-hex .pp-badge-art { width: 44px; height: 44px; }
.pp-hex.sm .pp-badge-art { width: 32px; height: 32px; }
.pp-hex.sm .pp-badge-icon .material-symbols-rounded { font-size: 24px; color: var(--esn-magenta); }
/* Season rail. */
.pp-rail { position: relative; height: 78px; margin: 6px 6px 4px; }
.pp-rail-line, .pp-rail-done { position: absolute; left: 0; top: 18px; height: 8px; border-radius: 999px; background: var(--border); width: 100%; }
.pp-rail-done { width: var(--pct); background: linear-gradient(90deg, var(--esn-cyan), var(--esn-green)); }
.pp-rail-dot { position: absolute; top: 4px; left: var(--x); transform: translateX(-50%); display: flex; flex-direction: column; align-items: center; gap: 6px; width: 64px; }
.pp-rail-dot b { width: 36px; height: 36px; border-radius: 50%; background: var(--card); border: 3px solid var(--border); color: var(--muted); display: flex; align-items: center; justify-content: center; font-size: .8rem; }
.pp-rail-dot.on b { background: var(--esn-green); border-color: var(--esn-green); color: var(--on-bright); }
.pp-rail-dot.cos:not(.on) b { border-color: #EAB308; color: #8a6a00; }  /* 1.77.0: 5:1 */
.pp-rail-dot small { font-size: .7rem; font-weight: 700; color: var(--muted); text-align: center; line-height: 1.15; }
@media (max-width: 480px) { .pp-rail-dot small { display: none; } }  /* 1.78.4: on a phone the labels overlapped and were cut; the list below names each reward */
.pp-rail-dot.on small { color: var(--ink); }
/* 1.76.0: dots sit at (i + 1) / n of the rail, not at their stamp count (three
   tiers landed on top of each other on a phone); only the last one is pulled
   in so its label stays inside the card. */
.pp-rail-dot.pp-rail-last { transform: translateX(calc(-100% + 18px)); }
@media (max-width: 480px) {
  .pp-rail .pp-rail-dot small { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; }  /* 1.76.0: the tier name stays readable to a screen reader */
  .pp-rail { height: 44px; }
}

/* ---- 1.29.0: passport 3 - twelve levels, hours, crew ladder, friendship ---- */
.pp-glow-6 .esncard { box-shadow: 0 0 0 3px rgba(212, 160, 23, .8), 0 10px 38px rgba(212, 160, 23, .45); animation: ppGlowPulseGold 2.8s ease-in-out infinite; }
/* the level ladder */
.pp-ladder { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 6px; }
.pp-ladder li { position: relative; display: grid; grid-template-columns: 26px 1fr; grid-template-rows: auto auto; column-gap: 8px; align-items: center; padding: 8px 10px; border: 1px solid var(--border); border-radius: 10px; background: var(--card); }
.pp-ladder li.done { opacity: 1; }
.pp-ladder li:not(.done):not(.here) { opacity: 1; color: var(--muted); }  /* 1.77.0: dimmed by colour, not opacity (the small text fell to 2.5:1) */
.pp-ladder li.here { opacity: 1; border-color: var(--lc); box-shadow: 0 0 0 2px color-mix(in srgb, var(--lc) 30%, transparent); padding-right: 38px; }
/* Passport level chips: the ink comes with the colour */
.pp-ladder-n { grid-row: span 2; width: 26px; height: 26px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: .75rem; font-weight: 900; background: var(--lc); color: var(--on-lc, #fff); }
.pp-ladder li:not(.done):not(.here) .pp-ladder-n { background: transparent; color: var(--lc); box-shadow: inset 0 0 0 2px var(--lc); }
.pp-ladder strong { font-size: .8rem; line-height: 1.2; }
.pp-ladder small { font-size: .75rem; color: var(--muted); }
.pp-ladder em { position: absolute; top: 6px; right: 8px; font-style: normal; font-size: .75rem; font-weight: 800; text-transform: uppercase; letter-spacing: .05em; color: var(--lc); }
.pp-xp-parts { margin-top: 14px; }
.pp-xp-parts > strong { display: block; font-size: .85rem; margin-bottom: 6px; }
.pp-xp-part { display: grid; grid-template-columns: 120px 1fr 44px; align-items: center; gap: 10px; font-size: .8rem; padding: 3px 0; }
.pp-xp-part b { text-align: right; font-variant-numeric: tabular-nums; }
.pp-xp-part-bar { height: 6px; border-radius: 3px; background: var(--surface2); overflow: hidden; }
.pp-xp-part-bar i { display: block; height: 100%; border-radius: 3px; background: var(--esn-cyan); }
/* the volunteer track */
.pp-vol-top { display: flex; align-items: center; gap: 14px; }
.pp-vol-ring { flex: none; width: 58px; height: 58px; border-radius: 50%; display: flex; align-items: center; justify-content: center; background: conic-gradient(var(--vc) var(--vdeg), rgba(128, 128, 160, .22) 0deg); }
.pp-vol-ring span { width: 46px; height: 46px; border-radius: 50%; background: var(--card); display: flex; align-items: center; justify-content: center; font-weight: 900; font-size: 1.15rem; color: var(--accent-text); }
.pp-vol-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.pp-vol-main strong { font-size: 1.05rem; color: var(--accent-text); }
.pp-vol-main small { font-size: .8rem; color: var(--muted); }
.pp-vol-main .pp-xp-bar { margin-top: 6px; background: var(--surface2); }
/* friendship */
.pp-friend-tier { flex: none; display: inline-flex; align-items: center; gap: 4px; font-size: .75rem; font-weight: 700; padding: 3px 8px; border-radius: 999px; background: var(--surface2); color: var(--muted); white-space: nowrap; }
.pp-friend-tier .material-symbols-rounded { font-size: 14px; }
.pp-friend-tier.tier-1 { color: var(--esn-cyan); }
.pp-friend-tier.tier-2 { color: var(--esn-green); background: color-mix(in srgb, var(--esn-green) 12%, transparent); }
.pp-friend-tier.tier-3 { color: var(--esn-orange); background: color-mix(in srgb, var(--esn-orange) 12%, transparent); }
.pp-friend-tier.tier-4 { color: var(--esn-magenta); background: color-mix(in srgb, var(--esn-magenta) 12%, transparent); }
.pp-circle { margin-top: 12px; padding-top: 10px; border-top: 1px solid var(--border); }
.pp-circle > strong { display: flex; align-items: center; gap: 6px; font-size: .85rem; margin-bottom: 6px; }
.pp-circle-row { display: grid; grid-template-columns: 22px 1fr auto auto; align-items: center; gap: 10px; padding: 5px 8px; border-radius: var(--r-sm); font-size: .85rem; }
.pp-circle-row.me { background: color-mix(in srgb, var(--esn-cyan) 12%, transparent); font-weight: 800; }
.pp-circle-pos { color: var(--muted); font-variant-numeric: tabular-nums; text-align: right; }
.pp-circle-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pp-circle-lvl { font-size: .75rem; }
.pp-circle-row b { font-variant-numeric: tabular-nums; }
/* the board's view */
.pp-lvl-chip { display: inline-flex; align-items: center; justify-content: center; min-width: 22px; height: 22px; padding: 0 5px; border-radius: 11px; background: var(--lc); font-size: .75rem; font-weight: 900; vertical-align: middle; color: var(--on-lc, #fff); }
.pp-lvl-chip.lg { min-width: 40px; height: 40px; border-radius: 20px; font-size: 1.05rem; }
.pp-lvl-xp { font-size: .8rem; font-variant-numeric: tabular-nums; color: var(--muted); }
.pp-admin-card { margin: 12px 0; }
.pp-admin-head { display: flex; align-items: center; gap: 12px; }
.pp-admin-head strong { display: block; }
.pp-admin-facts { display: flex; flex-wrap: wrap; gap: 6px 16px; margin-top: 10px; font-size: .85rem; color: var(--muted); }
.pp-admin-facts b { color: var(--ink); }
.pp-board-list li { display: flex; align-items: center; gap: 10px; }
.pp-bl-pos { flex: none; width: 20px; text-align: right; font-weight: 800; color: var(--muted); font-variant-numeric: tabular-nums; }
.pp-bl-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.pp-bl-name { font-weight: 700; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pp-board-list .vb-val { flex: none; }
.pp-ladder li.here em { color: var(--accent-text); }  /* 1.29.4: one system */
/* passport level colours used as text: darkened just enough in the light theme */
html:not([data-theme="dark"]) .pp-ladder li:not(.done):not(.here) .pp-ladder-n { color: color-mix(in srgb, var(--lc) 72%, #000); }
@media (max-width: 480px) {
  .pp-friend-tier { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  .pp-glow-6 .esncard { animation: none; }
}

/* ---- 1.29.1: the passport, structured - tabs, one block style, one type scale ---- */
.pp-tabs { position: sticky; top: var(--hdr, 0px); z-index: 5; display: flex; gap: 2px; padding: 3px; margin: 14px 0 12px; background: var(--surface2); border: 1px solid var(--border); border-radius: var(--r-md); overflow-x: auto; scrollbar-width: none; }
.pp-tabs::-webkit-scrollbar { display: none; }
.pp-tab { flex: 1 0 auto; display: inline-flex; align-items: center; justify-content: center; gap: 6px; min-height: 38px; padding: 6px 12px; border: 0; border-radius: 9px; background: transparent; color: var(--muted); font: inherit; font-size: .85rem; font-weight: 700; cursor: pointer; white-space: nowrap; }
.pp-tab .material-symbols-rounded { font-size: 16px; }
.pp-tab b { font-size: .75rem; font-weight: 800; padding: 1px 6px; border-radius: var(--r-sm); background: var(--card); color: var(--muted); font-variant-numeric: tabular-nums; }
.pp-tab:hover { color: var(--ink); background: var(--hover); }
.pp-tab.active { background: var(--card); color: var(--ink); box-shadow: 0 1px 2px rgba(16, 18, 60, .14); }
.pp-tab.active b { background: var(--esn-cyan); color: var(--on-bright); }
html[data-theme="dark"] .pp-tab.active { background: #2f3266; color: #fff; box-shadow: none; }
.pp-panel[hidden] { display: none; }
/* every section is the same card with the same header */
.pp-block, .pp-panel > .form-card, .pp-panel .pp-quests, .pp-panel .pp-next { background: var(--card); border: 1px solid var(--border); border-radius: var(--r-lg); box-shadow: none; padding: 16px; margin: 0 0 12px; }
.pp-block-h { display: flex; align-items: center; flex-wrap: wrap; gap: 4px 10px; margin: 0 0 12px; font-size: 1rem; font-weight: 800; color: var(--ink); line-height: 1.3; }
.pp-block-h > .material-symbols-rounded:first-child { width: 30px; height: 30px; border-radius: 9px; display: inline-flex; align-items: center; justify-content: center; font-size: 16px; background: var(--surface2); color: var(--esn-dark); flex: none; }
html[data-theme="dark"] .pp-block-h > .material-symbols-rounded:first-child { color: var(--esn-cyan); }
.pp-block-h .form-hint { font-size: .8rem; font-weight: 500; color: var(--muted); }
.pp-block-h .pp-count-bar { margin-left: auto; width: 96px; flex: none; }
.pp-block-b { padding: 0; }
.pp-block .pp-section-body, .pp-block > .pp-block-b > .form-card { padding: 0; border: 0; background: none; box-shadow: none; }
/* one progress colour: cyan everywhere under the cover */
.pp-panel .pp-quest-bar i, .pp-panel .pp-badge-bar i, .pp-panel .visa-bar i, .pp-panel .pp-count-bar i, .pp-panel .pp-xp-part-bar i { background: var(--esn-cyan) !important; }
/* calmer collection cards: neutral cards, colour only in the icon and the tier word */
.pp-panel .visa-card { box-shadow: none; border: 1px solid var(--border); border-top: 3px solid var(--tier, var(--border)); background: var(--card); }
.pp-panel .visa-card.top { box-shadow: none; }
.pp-panel .visa-card:not(.got) { border-top-color: var(--border); }
.pp-panel .pp-badge { background: var(--card); border: 1px solid var(--border); box-shadow: none; }
.pp-panel .pp-badge small { font-size: .75rem; color: var(--muted); }
.pp-panel .pp-badge strong { font-size: .85rem; }
/* one type scale inside the panels */
.pp-panel .form-hint { font-size: .8rem; }
.pp-panel .stamp-page-foot { font-size: .75rem; }
.pp-stamps .pp-month-head strong { font-size: .9rem; }
.pp-panel .pp-archive { margin-top: 10px; }
.pp-panel .pp-archive > summary { font-size: .9rem; font-weight: 700; }
.pp-block { border-radius: var(--radius); }  /* 1.29.4: colour follow-ups */
@media (max-width: 520px) {
  .pp-tab { padding: 6px 9px; }
  .pp-tab .pp-tab-l { display: none; }
  .pp-tab.active .pp-tab-l { display: inline; }
}

/* ---- 1.76.0: the passport page audit ---- */
/* the claim pill on the cover: a reached season tier with its reward still unclaimed */
.pp-cover-pill { display: inline-flex; align-items: center; gap: 6px; margin: 12px 0 0; padding: 7px 12px; border: 1px solid rgba(255, 255, 255, .35); border-radius: 999px; background: var(--esn-magenta); color: #fff; font: inherit; font-size: .8rem; font-weight: 800; cursor: pointer; }
.pp-cover-pill:hover { background: #d1007c; }
/* the bucketlist tile on the cover is a link to the guide */
.pp-tile-a { display: block; color: inherit; text-decoration: none; }
.pp-tile-a:hover { text-decoration: none; }
.pp-tile-a:hover span { color: #fff; }
/* quest to event: the event that would complete the quest, under its title */
.pp-quest-go { font-size: .75rem; font-weight: 700; color: var(--accent-text); text-decoration: none; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pp-quest-go:hover { text-decoration: underline; }
/* the level ladder: four rungs in view, the whole ladder folded away */
.pp-ladder-all { margin: 8px 0 0; }
.pp-ladder-all > summary { font-size: .85rem; font-weight: 700; }
.pp-ladder-all .pp-section-body { padding-top: 8px; }
/* the visa sheet: one row per event, each a link to the event */
.pp-sheet-h { display: flex; align-items: center; gap: 8px; margin: 0 0 8px; font-size: 1.05rem; }
.pp-sheet-list { display: flex; flex-direction: column; max-height: min(56dvh, 420px); overflow-y: auto; margin: 0 -6px; }
.pp-sheet-row { display: flex; align-items: center; gap: 10px; padding: 9px 6px; border-top: 1px solid var(--border); color: inherit; text-decoration: none; font-size: .9rem; }
.pp-sheet-row:first-child { border-top: 0; }
a.pp-sheet-row:hover { background: var(--hover); text-decoration: none; }
.pp-sheet-date { flex: none; width: 92px; font-size: .8rem; color: var(--muted); font-variant-numeric: tabular-nums; }
.pp-sheet-title { flex: 1; min-width: 0; font-weight: 700; }
.pp-sheet-row .chev { color: var(--muted); }

/* 1.33.0: the certificate row on the passport's Crew tab. */
.pp-cert { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; padding: 12px 14px; border: 1px dashed var(--border); border-radius: var(--r-md); background: var(--surface2); }
.pp-cert > div { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1 1 240px; }
.pp-cert strong { display: flex; align-items: center; gap: 6px; }

/* ---- Door passes (1.1.30) -------------------------------------------
   "I'm attending" on events without in-app tickets. The verdict panel is
   deliberately loud: at a dark, busy entrance a volunteer must never
   mistake a paying pass for free entry, so free is green with a card icon
   and paying is orange with the amount spelled out. */
.door-pass {
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  padding: 12px;
  margin-top: 12px;
  background: var(--bg);
}
.door-pass.mine { border-color: var(--esn-green); }
.door-pass .door-lead { font-size: 1rem; margin: 0 0 8px; display: flex; align-items: center; gap: 6px; }
.door-pass .btn-block { margin-top: 4px; }
.door-pass .form-hint { margin: 8px 0 0; }
.door-verdict {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  text-align: center;
  border-radius: var(--r-md);
  padding: 12px 10px;
  margin: 10px 0;
  color: #fff;
  line-height: 1.25;
}
.door-verdict.free { background: var(--esn-green); color: var(--on-bright); }
.door-verdict.pay { background: var(--esn-orange); color: var(--on-bright); }
/* Partner events: we run no door and know no price, so the panel claims
   nothing about entry - it only says "we scan this to count you in". */
.door-verdict.info { background: var(--esn-dark); }
.door-verdict .material-symbols-rounded { font-size: 28px; }
.door-verdict span { font-size: 1.05rem; font-weight: 900; letter-spacing: .6px; }
.door-verdict small { font-size: .8rem; font-weight: 700; opacity: .92; }
/* The scanner version fills the screen - readable at arm's length. */
.door-verdict.big { padding: 18px 12px; margin: 14px 0; border-radius: var(--r-lg); }
.door-verdict.big .material-symbols-rounded { font-size: 44px; }
.door-verdict.big span { font-size: 1.7rem; letter-spacing: .8px; }
.door-verdict.big small { font-size: .9rem; }
/* A link inside the pass verdict (get your ticket from the partner) stays readable on the dark box. */
.door-verdict a { color: inherit; text-decoration: underline; font-weight: 700; }  /* 1.15.0: colours per category */
.buy-box .door-pass { border: 0; background: transparent; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 10px; }  /* 1.29.3: event page polish */
.buy-box .door-pass .btn-block { margin: 0; }
.buy-box .door-pass .btn-sm { align-self: flex-start; }
.buy-box .door-pass .form-hint { margin: 0; }
.buy-box .door-pass .ev-going { margin: 0; font-size: .85rem; color: var(--muted); }
/* The door verdict as one row (icon, two lines) instead of a tall block */
.door-verdict.row { flex-direction: row; text-align: left; gap: 12px; padding: 10px 14px; align-items: center; }  /* 1.29.4: sweep */
.door-verdict.row .material-symbols-rounded { font-size: 24px; flex: none; }
.door-verdict.row > div { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.door-verdict.row span { font-size: .95rem; letter-spacing: .2px; }
.door-verdict.row small { font-size: .8rem; }
.buy-box .door-pass .door-verdict { margin: 0; }
.door-verdict.free a, .door-verdict.pay a { color: inherit; }  /* 1.29.4: one system */
@media (max-width: 380px) {
  .door-verdict.big span { font-size: 1.3rem; }
}

/* ---- People cards: /admin/team and /alumni (1.1.33) -------------------
   The team page used to be one dense table of dropdowns. It is now a set of
   cards grouped by organigram box, so the first question ("who is who, and
   who can take a shift?") is answered by looking, and the editing controls
   live in a drawer on the card you tapped. /alumni uses the same card. */
.tgroup { margin: 0 0 20px; }
.tgroup-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 10px; }
.tgroup-n {
  background: var(--esn-dark);
  color: #fff;
  border-radius: 20px;
  min-width: 22px;
  padding: 1px 7px;
  font-size: .8rem;
  font-weight: 900;
  text-align: center;
}
.tgrid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 12px;
}
.tcard {
  background: var(--card);
  border: 1px solid var(--border);
  border-left: 4px solid var(--esn-cyan);
  border-radius: var(--r-md);
  padding: 12px 14px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-width: 0;
}
.tcard.is-open { border-left-color: var(--esn-magenta); box-shadow: var(--shadow-lg); }
.tcard.is-svc { border-left-color: #9aa0b8; opacity: .85; }
.tcard-top { display: flex; align-items: center; gap: 10px; min-width: 0; }
.tcard-id { min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.tcard-id strong { font-size: 1rem; line-height: 1.25; overflow-wrap: anywhere; }
.tcard-id small { overflow-wrap: anywhere; font-size: .75rem; }
.tcard-func { font-size: .85rem; font-weight: 700; color: var(--magenta-text); }
.tcard-chips { display: flex; flex-wrap: wrap; gap: 5px; }
.tcard-chips .tchip.al-yr { white-space: normal; max-width: 100%; } /* 1.78.11: one chip per board year with its function; a long function wraps */
.tchip {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  border: 1px solid var(--border);
  background: var(--bg);
  color: var(--muted);
  border-radius: 20px;
  padding: 2px 8px;
  font-size: .75rem;
  font-weight: 700;
  white-space: nowrap;
}
.tchip .material-symbols-rounded { font-size: 14px; }
.tchip.role { background: var(--esn-dark); border-color: var(--esn-dark); color: #fff; }
/* GREEN = can take shifts, RED = cannot. */
.tchip.yes { background: rgba(122, 193, 67, .16); border-color: rgba(122, 193, 67, .5); color: var(--green-text); }
.tchip.no { background: rgba(215, 38, 61, .1); border-color: rgba(215, 38, 61, .35); color: #b51f33; }
.tchip.svc { background: #edeef5; color: #5f627a; }
/* Not filled in yet - a gap to close, not a refusal, so it stays quiet
   rather than borrowing the red that means "no" everywhere else. */
.tchip.missing { background: transparent; border-style: dashed; color: var(--muted); }
html[data-theme="dark"] .tchip.no { color: #ff8fa0; }
html[data-theme="dark"] .tchip.svc { background: #2a2c44; color: #b9bcd2; }
.tcard-foot {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  border-top: 1px dashed var(--border);
  padding-top: 8px;
  margin-top: auto;
}
.tcard-editor {
  border-top: 1px dashed var(--border);
  padding-top: 10px;
}
.tcard-editor .form-grid { gap: 10px; }
.tcard-editor .body-picks { display: flex; flex-wrap: wrap; gap: 4px 12px; }
.tcard-foot small { flex: 1 0 100%; margin-right: 0; }  /* 1.15.0: colours per category */
.tcard-foot > .btn:first-child, .tcard-foot > .btn:first-of-type { margin-left: 0; }
@media (max-width: 560px) {
  .tgrid { grid-template-columns: minmax(0, 1fr); }
}

/* ---- Shiftlists: fold what needs nothing (1.1.33) --------------------- */
.shift-sum { display: inline-flex; align-items: center; gap: 6px; flex-wrap: wrap; margin-left: auto; }
.shift-sum .av-stack .av + .av { margin-left: -6px; }  /* 1.78.16: who is on the shiftlist, as faces */
.shift-event-body { margin-top: 10px; min-width: 0; overflow-wrap: anywhere; }
.shift-event-links { display: flex; gap: 14px; flex-wrap: wrap; margin: 0 0 8px; font-size: .85rem; font-weight: 700; }
.shift-event-links a { display: inline-flex; align-items: center; gap: 4px; }

/* ---- The ticket (1.1.33) ---------------------------------------------
   A real ticket instead of a panel: the event's own accent on the top half,
   a punched perforation, and the QR on the stub below. The notches are
   circles in the PAGE colour drawn half outside the card, which `overflow:
   hidden` then bites out of the edge. */
.tkt {
  position: relative;
  max-width: 420px;
  margin: 28px auto;
  background: var(--card);
  border-radius: 18px;
  overflow: hidden;
  box-shadow: 0 18px 40px rgba(29, 31, 49, .18), 0 2px 6px rgba(29, 31, 49, .08);
  text-align: center;
}
html[data-theme="dark"] .tkt { box-shadow: 0 18px 40px rgba(0, 0, 0, .5); }
.tkt-top {
  position: relative;
  background: var(--accent, var(--esn-dark));
  padding: 20px 20px 22px;
  display: flex;
  align-items: flex-start;
  gap: 12px;
  text-align: left;
  overflow: hidden;
  color: var(--on-accent, #fff);
}
.tkt-img {
  position: absolute;
  inset: 0;
  background-size: cover;
  background-position: center;
  opacity: .3;
}
.tkt-img::after { content: ""; position: absolute; inset: 0; background: rgba(18, 20, 56, .32); }
.tkt-top-in { position: relative; z-index: 1; flex: 1; min-width: 0; }
.tkt-kicker {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: .75rem;
  font-weight: 900;
  letter-spacing: 1.4px;
  text-transform: uppercase;
  border-radius: 20px;
  padding: 3px 10px;
  background: color-mix(in srgb, currentColor 16%, transparent);
}
.tkt-kicker .material-symbols-rounded { font-size: 14px; }
.tkt-meta { display: flex; flex-direction: column; gap: 2px; font-size: .8rem; opacity: .95; }
.tkt-meta span { display: inline-flex; align-items: center; gap: 5px; }
.tkt-meta .material-symbols-rounded { font-size: 14px; }
.tkt-day {
  position: relative;
  z-index: 1;
  flex: none;
  background: #fff;
  color: var(--esn-dark);
  border-radius: var(--r-md);
  width: 54px;
  padding: 7px 0 6px;
  text-align: center;
  box-shadow: 0 3px 10px rgba(0, 0, 0, .18);
}
.tkt-day b { display: block; font-size: 1.45rem; font-weight: 900; line-height: 1; }
.tkt-day span { display: block; font-size: .75rem; font-weight: 900; letter-spacing: 1.2px; text-transform: uppercase; margin-top: 2px; }
/* the tear line */
.tkt-rip {
  position: relative;
  height: 28px;
  background-color: var(--card);
  background-image: repeating-linear-gradient(90deg, var(--border) 0 7px, transparent 7px 16px);
  background-size: calc(100% - 40px) 2px;
  background-position: center;
  background-repeat: no-repeat;
}
.tkt-rip::before,
.tkt-rip::after {
  content: "";
  position: absolute;
  top: 50%;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: var(--bg);
  transform: translateY(-50%);
}
.tkt-rip::before { left: -14px; }
.tkt-rip::after { right: -14px; }
.tkt-stub {
  padding: 6px 20px 24px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
}
/* Brand colours as text on white: the darker text variants */
.tkt-valid {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  background: rgba(122, 193, 67, .16);
  border: 1px solid rgba(122, 193, 67, .45);
  border-radius: 20px;
  padding: 5px 12px;
  font-size: .8rem;
  font-weight: 800;
  color: var(--green-text);
}
.tkt-valid .material-symbols-rounded { font-size: 16px; }
.tkt .qr-box { border: none; padding: 10px; border-radius: var(--r-md); box-shadow: 0 2px 10px rgba(29, 31, 49, .12); }
.tkt-holder {
  margin: 0;
  font-size: 1rem;
  font-weight: 900;
  letter-spacing: 1.6px;
  text-transform: uppercase;
  overflow-wrap: anywhere;
}
.tkt-code {
  margin: 0;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: .75rem;
  color: var(--muted);
  display: inline-flex;
  align-items: center;
  gap: 4px;
  overflow-wrap: anywhere;
}
.tkt-code .material-symbols-rounded { font-size: 14px; }
.tkt.is-in .qr-box { opacity: .5; }
.tkt.is-in .tkt-top { filter: saturate(.65); }
.tkt .ticket-facts { max-width: 320px; }
.tkt .tk-in, .tkt .door-verdict, .tkt .ticket-more { max-width: 320px; width: 100%; }
/* the ticket: the type takes the whole top and gets its own band */
.tkt-type { display: flex; align-items: center; justify-content: center; gap: 10px; padding: 10px 16px; background: var(--c); color: #fff; font-weight: 900; font-size: 1.05rem; letter-spacing: .4px; text-transform: uppercase; }  /* 1.19.0: ticket types with a colour */
.tkt-type i { width: 14px; height: 14px; border-radius: 50%; background: #fff; opacity: .9; flex: none; }
/* Ticket page (1.29.3): under the name one quiet line (tickets, price,
   code), then a row of equal action tiles; the options open under them. */
.tkt-line { margin: -4px 0 0; font-size: .8rem; color: var(--muted); text-align: center; display: flex; align-items: center; justify-content: center; gap: 6px; flex-wrap: wrap; }  /* 1.29.3: event page polish */
.tkt-line .mono { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: .75rem; letter-spacing: .3px; }
.tkt-sep { opacity: .6; }
.tkt-acts { display: flex; gap: 8px; width: 100%; max-width: 360px; margin-top: 14px; }
.tkt-acts > * { flex: 1 1 0; min-width: 0; }
.tkt-act {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px;
  width: 100%; padding: 12px 6px 10px; border-radius: var(--r-md); border: 1px solid var(--border); background: var(--card);
  color: var(--ink); font-family: inherit; font-size: .75rem; font-weight: 700; cursor: pointer; text-decoration: none; list-style: none;
  transition: background .15s, border-color .15s;
}
.tkt-act::-webkit-details-marker { display: none; }
.tkt-act .material-symbols-rounded { font-size: 20px; color: var(--esn-cyan); }
.tkt-act:hover { background: var(--hover); text-decoration: none; }
.tkt-act.on, .tkt-act-menu[open] > .tkt-act { border-color: var(--esn-cyan); background: color-mix(in srgb, var(--esn-cyan) 10%, transparent); }
.tkt-act-rate .material-symbols-rounded { color: var(--esn-orange); }
.tkt-act-menu { position: relative; display: block; }
.tkt-act-menu .more-menu-list { left: 50%; right: auto; transform: translateX(-50%); }
.tkt-stub .ticket-more { margin-top: 10px; padding: 10px; border-radius: var(--r-md); border: 1px solid var(--border); background: var(--bg); }
.tkt-stub .ticket-more-body { margin-top: 0; gap: 4px; }
.tkt-closed { text-align: center; margin: 10px 0 0; }
.tkt-stub .tk-opt { display: grid; grid-template-columns: auto 1fr; column-gap: 10px; row-gap: 1px; align-items: center; text-align: left; padding: 10px 12px; border-radius: 10px; }
.tkt-stub .tk-opt > .material-symbols-rounded { grid-row: 1 / 3; font-size: 20px; }
.tkt-stub .tk-opt small { grid-column: 2; }
.tkt-stub .ticket-more-body .form-hint { text-align: center; margin: 4px 0 0; }
/* The mark page (coming, interested) shares the ticket shape */
.tkt-mark .tkt-line { display: block; text-align: center; margin: 4px 0 0; line-height: 1.5; }  /* 1.29.4: sweep */
.tkt-act-quiet .material-symbols-rounded { color: var(--muted); }
.tkt-act-hot .material-symbols-rounded { color: var(--esn-magenta); }
.tkt-line .hint-i { vertical-align: -4px; }
.tkt-line .material-symbols-rounded.mi-sm { font-size: 14px; vertical-align: -3px; }
.tkt-form { display: flex; align-items: center; gap: 10px; width: 100%; box-sizing: border-box; align-self: stretch; margin: 12px 0 0; padding: 10px 12px; border-radius: var(--r-md); text-decoration: none; color: inherit; text-align: left; font-size: .85rem; }  /* 1.34.0: Tally. The form strip on a ticket */
.tkt-form > .tkt-form-text { display: flex; flex-direction: column; min-width: 0; flex: 1; text-align: left; }
.tkt-form strong { display: block; line-height: 1.25; }
.tkt-form > .material-symbols-rounded { flex-shrink: 0; }
.tkt-form small { color: var(--muted); }
.tkt-form.todo { background: color-mix(in srgb, var(--esn-orange) 14%, var(--card)); border: 1px solid color-mix(in srgb, var(--esn-orange) 45%, transparent); }
.tkt-form.todo > .material-symbols-rounded:first-child { color: var(--esn-orange); }
.tkt-form.done { background: color-mix(in srgb, var(--esn-green) 12%, var(--card)); border: 1px solid color-mix(in srgb, var(--esn-green) 40%, transparent); }
.tkt-form.done > .material-symbols-rounded:first-child { color: var(--esn-green); }
.tkt-form-acts { display: flex; gap: 14px; flex-wrap: wrap; margin-top: 4px; font-size: .85rem; }
.tkt-form-acts .linkish { padding: 0; }
@media (max-width: 420px) {
  .tkt { margin: 18px auto; border-radius: var(--r-lg); }
}

/* ---- 1.19.0: ticket types with a colour ----
   One dot everywhere a type is named; a band across the ticket and the
   door verdict where the colour has to be seen from a metre away. */
.type-dot { display: inline-block; width: 12px; height: 12px; border-radius: 50%; background: var(--c); vertical-align: -1px; margin-right: 6px; flex: none; box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .12); }
.type-dot.lg { width: 16px; height: 16px; vertical-align: -2px; }

/* ============================================================
   1.29.2 - small app comforts
   ============================================================ */
/* Relative time next to a date ("in 2 h", "tomorrow") */
.rel-t {
  display: inline-block; margin-left: 6px; padding: 1px 8px; border-radius: 999px;
  font-size: .75rem; font-weight: 700; line-height: 1.5; vertical-align: 1px;
  background: color-mix(in srgb, var(--esn-cyan) 14%, transparent); color: var(--accent-text);
  white-space: nowrap;
}
/* Tonight's ticket, one tap from home */
.tonight-card {
  display: flex; align-items: center; gap: 14px; margin: 14px 0 14px; padding: 14px 16px; background: var(--card); border: 1px solid var(--border);
  border-left: 4px solid var(--esn-green); box-shadow: var(--shadow);
  color: var(--ink); text-decoration: none; border-radius: var(--radius);
}
.tonight-card:hover { background: var(--hover); text-decoration: none; }
html[data-theme="dark"] .tonight-card { color: var(--ink); }
.tonight-ic {
  flex: 0 0 44px; height: 44px; border-radius: var(--r-md); display: flex; align-items: center; justify-content: center;
  background: color-mix(in srgb, var(--esn-green) 16%, transparent); color: var(--esn-green);
}
.tonight-ic .material-symbols-rounded { font-size: 28px; }
.tonight-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.tonight-k { font-size: .75rem; font-weight: 700; color: var(--muted); text-transform: uppercase; letter-spacing: .4px; }
.tonight-k .rel-t { text-transform: none; letter-spacing: 0; }
.tonight-main > b { font-size: 1rem; overflow: hidden; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; }  /* 1.69.6: two lines before the ellipsis (big text, long names) */
.tonight-main small { color: var(--muted); font-size: .85rem; overflow: hidden; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; }
.tonight-card .chev { color: var(--muted); font-size: 1.45rem; }
/* Tap a QR to show it full screen */
.qr-tap { cursor: zoom-in; }
.qr-big {
  position: fixed; inset: 0; z-index: 3000; background: #fff; color: #191a2e;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 14px;
  padding: 24px; cursor: zoom-out; animation: qrBigIn .16s ease-out;
}
.qr-big-code { background: #fff; padding: 8px; line-height: 0; }
.qr-big-code canvas, .qr-big-code img, .qr-big-code svg { display: block; width: 100%; height: auto; image-rendering: pixelated; }
.qr-big-cap { margin: 0; font-weight: 800; font-size: 1.15rem; text-align: center; }
.qr-big-hint { margin: 0; color: #676a80; font-size: .85rem; text-align: center; max-width: 32ch; }
/* Pull to refresh (installed app) */
.ptr {
  position: fixed; top: calc(env(safe-area-inset-top, 0px) + 56px); left: 50%; z-index: 2500;
  width: 40px; height: 40px; border-radius: 50%; display: flex; align-items: center; justify-content: center;
  background: var(--card); color: var(--muted); box-shadow: var(--shadow-lg); border: 1px solid var(--border);
  transform: translate(-50%, -44px); opacity: 0; pointer-events: none;
  transition: color .15s, background .15s;
}
.ptr.ready { color: var(--on-bright); background: var(--esn-cyan); border-color: var(--esn-cyan); }
.ptr.spin { color: var(--on-bright); background: var(--esn-cyan); border-color: var(--esn-cyan); opacity: 1; transition: transform .2s; }
.ptr.spin .material-symbols-rounded { animation: ptrSpin .8s linear infinite; }
html.save-data .ptr.spin .material-symbols-rounded { animation: ptrSpin .8s linear infinite !important; }
html[data-theme="dark"] .tonight-ic {
  color: color-mix(in srgb, var(--accent, var(--esn-cyan)) 55%, #fff);
  background: color-mix(in srgb, var(--accent, var(--esn-cyan)) 30%, transparent);
  --accent: var(--esn-green);
}  /* 1.29.4: sweep */

/* ---- Homepage news (1.1.33) ------------------------------------------
   Was a one-line strip that read like a system banner. Now a card with a
   cover, the headline and the opening line, linking straight to the post. */
.hnews {
  display: flex;
  gap: 14px;
  align-items: stretch;
  background: var(--card);
  border: 1px solid var(--border);
  border-left: 4px solid var(--esn-magenta);
  border-radius: var(--r-md);
  padding: 0;
  margin: 0 0 12px;
  overflow: hidden;
  color: inherit;
}
.hnews:hover { text-decoration: none; border-color: var(--esn-magenta); box-shadow: var(--shadow-lg); }
.hnews-img {
  flex: 0 0 104px;
  background-size: cover;
  background-position: center;
  min-height: 104px;
}
.hnews-ico {
  flex: 0 0 56px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--esn-magenta);
  background: var(--bg);
}
.hnews-main {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding: 12px 14px 12px 0;
}
.hnews-ico + .hnews-main { padding-left: 0; }
.hnews-main small { color: var(--muted); font-size: .75rem; }
.hnews-main strong { font-size: 1rem; line-height: 1.3; overflow-wrap: anywhere; }
.hnews-teaser {
  font-size: .85rem;
  color: var(--muted);
  line-height: 1.45;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.hnews-cta {
  margin-top: 4px;
  font-size: .8rem;
  font-weight: 800;
  display: inline-flex;
  align-items: center;
  gap: 3px;
  color: var(--magenta-text);
}
.hnews-cta .material-symbols-rounded { font-size: 14px; }
/* On a phone the newest post with a picture gets a full-width cover. On a
   wider screen that cover would be ~480 px tall and eat the whole first
   screen, so from 720px the lead goes back to a side-by-side row. */
.hnews.is-lead { flex-direction: column; }
.hnews.is-lead .hnews-img { flex: none; width: 100%; min-height: 0; aspect-ratio: 16 / 7; }
.hnews.is-lead .hnews-main { padding: 14px 16px 16px; }
.hnews.is-lead .hnews-main strong { font-size: 1.15rem; }
.hnews.is-lead .hnews-teaser { -webkit-line-clamp: 3; }
.hnews-img img { width: 100%; height: 100%; object-fit: cover; display: block; border-radius: inherit; }  /* 1.24.1: the news picture is an <img> the browser can prioritise */
@media (min-width: 720px) {
  .hnews.is-lead { flex-direction: row; }
  .hnews.is-lead .hnews-img {
    flex: 0 0 34%;
    width: auto;
    aspect-ratio: auto;
    min-height: 150px;
    max-height: 210px;
  }
  .hnews.is-lead .hnews-main { padding: 14px 16px 14px 0; }
  .hnews-img { max-height: 210px; }
}
@media (max-width: 400px) {
  .hnews-img { flex-basis: 88px; min-height: 88px; }
}

/* ---- Homepage audit fixes (1.1.35) ----------------------------------- */
.strip-stretch { position: absolute; inset: 0; border-radius: inherit; }
.strip-x {
  position: relative;
  z-index: 1;
  margin-left: auto;
  background: none;
  border: 0;
  color: var(--muted);
  font-size: 1.05rem;
  line-height: 1;
  cursor: pointer;
  min-width: 44px;
  min-height: 44px;
  border-radius: var(--r-sm);
}
.strip-x:hover { background: var(--hover); color: var(--ink); }
/* "You're going" replaces the price on an event you already hold. */
.going-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  background: rgba(122, 193, 67, .16);
  border: 1px solid rgba(122, 193, 67, .5);
  border-radius: 20px;
  padding: 3px 10px;
  font-size: .8rem;
  font-weight: 800;
  color: var(--green-text);
}
/* A welcome for people who are not signed in. */
.guest-panel {
  background: var(--card);
  border: 1px solid var(--border);
  border-left: 4px solid var(--esn-cyan);
  border-radius: var(--r-md);
  padding: 14px 16px 16px;
  margin: 0 0 18px;
}
.guest-panel p { font-size: .9rem; margin: 0 0 10px; }
.guest-panel .form-hint { margin: 8px 0 0; }
/* 1.69.3: the card tile for visitors */
.guest-card { display: flex; align-items: center; gap: 12px; margin: 12px 0 0; padding: 12px 14px; border-radius: var(--r-md); color: inherit; background: color-mix(in srgb, var(--esn-magenta) 9%, var(--card)); border: 1px solid color-mix(in srgb, var(--esn-magenta) 40%, var(--border)); }
.guest-card:hover { text-decoration: none; border-color: var(--esn-magenta); }
.guest-card-ic { flex: none; width: 40px; height: 40px; border-radius: 50%; display: flex; align-items: center; justify-content: center; background: var(--esn-magenta); color: #fff; }
.guest-card-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.guest-card-main strong { font-size: .95rem; }
.guest-card-main small { font-size: .8rem; color: var(--muted); line-height: 1.4; }
.guest-card .chev { color: var(--muted); font-size: 1.3rem; }

/* ---------- Event locations (/admin/venues, 1.1.38) ---------- */
.vgrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 14px; margin-bottom: 26px; }
.vcard {
  display: grid;
  grid-template-columns: 96px 1fr;
  grid-template-areas: "pic body" "foot foot" "editor editor";
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  overflow: hidden;
  box-shadow: var(--shadow);
}
.vcard[hidden] { display: none; }
.vcard-pic { grid-area: pic; position: relative; overflow: hidden; background: var(--surface2); min-height: 96px; }
.vcard-pic img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.vcard-ph { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; color: var(--muted); opacity: .5; }
.vcard-ph .material-symbols-rounded { font-size: 28px; }
.vcard-body { grid-area: body; padding: 11px 14px 4px; min-width: 0; }
.vcard-body h4 { margin: 0 0 3px; font-size: .95rem; }
.vcard-addr { margin: 0 0 7px; font-size: .8rem; }
.vcard-addr a, .vcard-addr .form-hint { display: inline-flex; align-items: center; gap: 3px; }
.vcard-chips { display: flex; flex-wrap: wrap; gap: 5px; min-width: 0; }
.vcard-chips .tchip { max-width: 100%; overflow: hidden; text-overflow: ellipsis; }
.vcard-stats { margin: 8px 0 0; font-size: .75rem; line-height: 1.45; }
.vn-months { color: var(--muted); font-size: .75rem; }
.vcard-foot { grid-area: foot; display: flex; justify-content: flex-end; padding: 6px 12px 10px; }
.vcard-editor { grid-area: editor; border-top: 1px solid var(--border); padding: 14px; background: var(--surface2); }
.vcard-editor[hidden] { display: none; }
.vcard-tags { display: flex; flex-wrap: wrap; gap: 4px 14px; margin-top: 6px; }
.vcard-tags .checkbox-row { margin: 0; white-space: nowrap; }
/* A button that reads as a link (the inline "show the numbers" toggle). */
.linkish {
  background: none; border: 0; padding: 0; font: inherit; color: var(--accent-text);
  cursor: pointer; text-decoration: underline; text-underline-offset: 2px; min-height: 30px; display: inline-flex; align-items: center;
}
.linkish:hover { opacity: .8; }
/* Icon-only button on narrow cards, label back when there is room (1.1.39). */
.vh-lbl { display: none; }
@media (min-width: 420px) {
  .vh-lbl { display: inline; }
}
@media (max-width: 520px) {
  .vcard { grid-template-columns: minmax(0, 1fr); grid-template-areas: "pic" "body" "foot" "editor"; }
  .vcard-pic { min-height: 120px; }
}

/* ---------- Shiftlists: long lists made navigable (1.1.39) ---------- */
details.shift-event > summary { cursor: pointer; list-style: none; }  /* 1.1.33: Shiftlists */
details.shift-event > summary::-webkit-details-marker { display: none; }
details.shift-event > summary::after {
  content: "▾";
  margin-left: 6px;
  font-size: .8rem;
  color: var(--muted);
  transition: transform .15s;
}
details.shift-event[open] > summary::after { transform: rotate(180deg); display: inline-block; }
details.shift-event.is-full:not([open]) { opacity: .78; }
details.shift-event.is-mine { border-left: 4px solid var(--esn-green); }
.shift-bar {
  position: sticky;
  top: calc(var(--hdr, 0px) - 1px);
  z-index: 5;
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin: 0 0 12px;
  padding: 8px 0;
  background: var(--bg);
}
.shift-bar .filter-chips { margin: 0; flex: 1 1 auto; min-width: 0; }
.shift-search {
  flex: 0 1 240px;
  min-width: 150px;
  height: 38px;
  padding: 0 12px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--card);
  color: var(--ink);
  font: inherit;
  font-size: .85rem;
}
.shift-bucket { margin: 0 0 18px; }
.shift-bucket[hidden] { display: none; }
.shift-bucket-head {
  display: flex;
  align-items: baseline;
  gap: 10px;
  flex-wrap: wrap;
  cursor: pointer;
  padding: 6px 0;
  list-style: none;
  border-bottom: 1px solid var(--border);
  margin-bottom: 12px;
}
.shift-bucket-head::-webkit-details-marker { display: none; }
.shift-bucket-title { margin: 0; font-size: 1rem; font-weight: 900; display: inline-flex; align-items: center; gap: 8px; }
.shift-bucket-head::after {
  content: "expand_more";
  font-family: "Material Symbols Rounded", sans-serif;
  margin-left: auto;
  color: var(--muted);
  transition: transform .15s ease;
}
.shift-bucket[open] > .shift-bucket-head::after { transform: rotate(180deg); }
/* Wide screens had one tall ribbon of cards with half the width empty. */
.shift-cols { display: grid; grid-template-columns: minmax(0, 1fr); gap: 14px; }
.shift-cols > .shift-event { margin: 0; }
.shift-event[hidden] { display: none; }
@media (min-width: 900px) {
  .shift-cols { grid-template-columns: repeat(auto-fill, minmax(420px, 1fr)); align-items: start; }
}

/* ---------- Pricing choice on the event form (1.1.42) ---------- */
.pricing-block > label:first-child { display: block; margin-bottom: 8px; }
.seg { display: inline-flex; flex-wrap: wrap; gap: 0; border: 1px solid var(--border); border-radius: 10px; overflow: hidden; background: var(--card); }
.seg-opt { position: relative; margin: 0; cursor: pointer; }
.seg-opt[hidden] { display: none; }
.seg-opt input { position: absolute; opacity: 0; inset: 0; margin: 0; cursor: pointer; }
/* 1.56.6: the label only (> span), never the icon inside it: the icon got the divider and the padding too */
.seg-opt > span {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 9px 14px; font-size: .85rem; font-weight: 700; color: var(--muted);
  border-right: 1px solid var(--border); min-height: 40px;
}
.seg-opt:last-child > span { border-right: 0; }
.seg-opt input:checked + span { background: var(--esn-dark); color: #fff; }
.seg-opt input:focus-visible + span { outline: 2px solid var(--esn-cyan); outline-offset: -2px; }
.seg-opt span .material-symbols-rounded { font-size: 16px; }
/* 1.49.0: the same switch made of buttons (the share studio) */
.seg-btn { border: 0; border-right: 1px solid var(--border); background: none; font: inherit; font-size: .8rem; font-weight: 700; color: var(--muted); min-height: 36px; padding: 6px 12px; cursor: pointer; white-space: nowrap; }
.seg-btn:last-child { border-right: 0; }
.seg-btn.active { background: var(--esn-dark); color: #fff; }
.seg-btn:focus-visible { outline: 2px solid var(--esn-cyan); outline-offset: -2px; }
.pricing-single { margin-top: 12px; }
.pricing-types { margin-top: 4px; }

/* ---------- Calendar header 2 (1.29.4) ---------- */
/* Calendar header (1.29.4): arrows around the month, Today beside it, the
   view switch on the right. One row on desktop, two on a phone. */
.cal-head2 { margin: 18px 0 12px; gap: 10px; }
.cal-nav { display: flex; align-items: center; gap: 4px; min-width: 0; }
.cal-nav h2 { margin: 0 4px; font-size: 1.3rem; }
.cal-head2 .cal-nav-buttons { gap: 8px; }
.cal-head2 .seg { border-radius: 9px; }
.cal-head2 .seg-opt > span { padding: 7px 12px; font-size: .8rem; display: inline-flex; align-items: center; gap: 5px; }
@media (max-width: 640px) {
  .cal-head2 { margin-top: 6px; }
  .cal-head2 .cal-nav { width: 100%; }
  .cal-head2 .cal-nav h2 { flex: 1; text-align: center; font-size: 1.15rem; }
  .cal-head2 .cal-nav-buttons { width: 100%; justify-content: space-between; flex-direction: row-reverse; flex-wrap: nowrap; }
  .cal-visual-lbl { display: none; }  /* 1.40.0: mobile polish from the September screenshots */
}

/* ---------- Celebrations ----------
   Spawned by JS, removed by JS on animationend. Fixed rather than absolute so
   a burst is never clipped by a card's overflow, and pointer-events none so
   it can never swallow a tap. */
.pp-burst { position: fixed; inset: 0; pointer-events: none; z-index: 60; overflow: hidden; }
.pp-burst span {
  position: absolute; width: 10px; height: 10px; border-radius: 2px;
  will-change: transform, opacity;
  animation: pp-confetti var(--d, 1.1s) cubic-bezier(.15, .6, .35, 1) forwards;
}
/* The level-up banner that rides on top of the burst. */
.pp-levelup {
  position: fixed; left: 50%; top: 38%; transform: translate(-50%, -50%);
  z-index: 61; pointer-events: none; text-align: center;
  padding: 18px 26px; border-radius: 18px; color: #fff;
  background: var(--navy-gradient);
  box-shadow: 0 18px 50px rgba(25, 26, 46, .45);
  animation: pp-levelup-in 2.6s cubic-bezier(.22, 1, .36, 1) both;
  overflow: hidden;
}
/* The section's five colours across the top, so the moment reads as ESN
   rather than as a generic toast. */
.pp-levelup::before {
  content: ""; position: absolute; top: 0; left: 0; right: 0; height: 5px;
  border-radius: 18px 18px 0 0;
  background: linear-gradient(90deg, var(--esn-dark) 20%, var(--esn-cyan) 20% 40%, var(--esn-magenta) 40% 60%, var(--esn-green) 60% 80%, var(--esn-orange) 80%);
}
.pp-levelup strong { display: block; font-size: 1.45rem; margin-top: 4px; }
.pp-levelup span { display: block; font-size: .8rem; opacity: .75; margin-top: 4px; letter-spacing: .04em; }

/* ---- 1.15.0: colours per category, pins with the partner's own logo, a globe
   that follows the theme and fills its card, menus that stay on top ---- */
/* Map tiles wear a style per map: soft colour on the deals page, grey on the
   maps that carry many pins, and both turn dark with the app. */
.tiles-soft { filter: saturate(.62) contrast(.94) brightness(1.04); }
.tiles-mono { filter: grayscale(1) contrast(.88) brightness(1.06); }
html[data-theme="dark"] .tiles-soft { filter: invert(1) hue-rotate(180deg) saturate(.5) brightness(.82) contrast(.88); }
html[data-theme="dark"] .tiles-mono { filter: invert(1) grayscale(1) brightness(.72) contrast(.9); }
/* A pin is the partner's logo in a ring of its category colour, or the
   category icon on a disc of it. Venues are the ESN blue with a calendar. */
.pin-wrap { background: none; border: 0; }
.pin { --c: var(--esn-cyan); width: 100%; height: 100%; border-radius: 50%; background: var(--c); color: #fff; display: flex; align-items: center; justify-content: center; border: 2.5px solid #fff; box-shadow: 0 2px 6px rgba(0, 0, 0, .35); overflow: hidden; box-sizing: border-box; transition: transform var(--t-fast) ease; }
.pin .material-symbols-rounded { font-size: 20px; color: #fff; }
.pin img { width: 100%; height: 100%; object-fit: cover; display: block; }
.pin.has-logo { background: #fff; border-color: var(--c); }
.pin.venue { border-radius: 9px; }
.pin.pin-sm .material-symbols-rounded { font-size: 14px; }
.leaflet-marker-icon:hover .pin, .pin.focus { transform: scale(1.12); }
.cat-dot { display: inline-block; width: 9px; height: 9px; border-radius: 50%; background: var(--c, var(--cat-other)); vertical-align: 0; margin-right: 4px; box-shadow: 0 0 0 1px rgba(0, 0, 0, .12); }
.chip .cat-dot { margin-right: 2px; }
/* Inbox rows: status, who, what and when, who has it - in columns. */
.inbox-item summary { justify-content: flex-start; gap: 10px; }
.inbox-item summary > .ib-status { flex: 0 0 92px; text-align: center; }
.inbox-item summary > .ib-who { flex: 1 1 160px; min-width: 0; margin: 0 !important; }
.inbox-item summary > .ib-who .person { max-width: 100%; }
.inbox-item summary > .ib-who .person-txt, .inbox-item summary > .ib-who .person-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.inbox-item summary > .ib-meta { flex: 0 1 auto; margin: 0 !important; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.inbox-item summary > .ib-wait, .inbox-item summary > .ib-by { flex: none; margin: 0 !important; }
.inbox-item summary > .ib-by { min-width: 64px; text-align: center; }
/* Team cards: the shift count beside the name, the footer text on its own
   row with the two buttons under it. */
.tcard-shifts { margin-left: auto; flex: none; display: flex; flex-direction: column; align-items: center; min-width: 46px; padding: 4px 6px; border-radius: 10px; background: var(--surface2); color: var(--ink); line-height: 1.1; }
.tcard-shifts b { font-size: 1.15rem; font-weight: 900; font-variant-numeric: tabular-nums; }
.tcard-shifts small { font-size: .75rem; color: var(--muted); font-weight: 700; text-transform: uppercase; letter-spacing: .3px; }
.tcard-shifts.none { opacity: .55; }
@media (max-width: 640px) {
  /* Two lines: status, who and the marker; then what and when, with who has it at the right. */
  .inbox-item summary { flex-wrap: wrap; row-gap: 6px; }
  .inbox-item summary > .ib-status { flex-basis: auto; }
  .inbox-item summary > .ib-who { flex: 1 1 auto; }
  .inbox-item summary::after { order: 2; margin-left: auto; }
  .inbox-item summary > .ib-meta { order: 5; flex: 1 1 0; min-width: 120px; }
  .inbox-item summary > .ib-wait, .inbox-item summary > .ib-by { order: 6; }
  .inbox-item summary > .ib-by:empty { display: none; }
}

/* 1.33.0: friends going, faces stacked, on the cards and on the event page. */
/* Rate last night (home). */
.rate-strip { display: flex; align-items: center; gap: 12px; background: var(--card); border: 1px solid var(--border); border-left: 4px solid var(--esn-orange); border-radius: var(--r-md); padding: 10px 14px; margin: 0 0 18px; position: relative; }
.rate-strip .news-strip-icon { color: var(--esn-orange); }
.rate-strip .news-strip-main { flex: 1; }
.rate-strip .rate-stars { justify-content: flex-start; margin-top: 4px; gap: 2px; }
.rate-strip .star { font-size: 1.7rem; padding: 0 2px; }
.rate-strip .rate-done { color: var(--green-text); }  /* 1.29.4: one system */

/* ============================================================
   1.29.3 - event page polish: icon facts, a flat ticket box, one board bar
   ============================================================ */
html[data-theme="dark"] .tk-quiet, html[data-theme="dark"] .tk-rate { border-color: transparent; }
html[data-theme="dark"] .tkt-act { color: var(--ink); }
html[data-theme="dark"] .getcard-ic {
  color: color-mix(in srgb, var(--accent, var(--esn-cyan)) 55%, #fff);
  background: color-mix(in srgb, var(--accent, var(--esn-cyan)) 30%, transparent);
  --accent: var(--esn-cyan);
}  /* 1.29.4: sweep */
html[data-theme="dark"] .ev-have-ic { color: var(--green-text); }

/* 1.33.0: Promote (poster, story, post). */
.promo { display: grid; grid-template-columns: minmax(260px, 420px) minmax(0, 1fr); gap: 22px; align-items: start; }
.promo-preview { position: sticky; top: 76px; }
.promo-stage { position: relative; width: 100%; border-radius: var(--r-lg); overflow: hidden; background: var(--surface2); box-shadow: var(--shadow-lg); border: 1px solid var(--border); }
.promo-stage img { display: block; width: 100%; height: auto; }
.promo-stage.promo-story { aspect-ratio: 9 / 16; }
.promo-stage.promo-poster { aspect-ratio: 210 / 297; }
.promo-stage.promo-post { aspect-ratio: 1; }
/* Visuals (1.35.0): the same stage in the studio's shapes */
.promo-stage.studio-story { aspect-ratio: 9 / 16; }
.promo-stage.studio-post { aspect-ratio: 4 / 5; }
.promo-stage.studio-poster { aspect-ratio: 210 / 297; }
.promo-stage.studio-news { aspect-ratio: 16 / 9; }
.studio-kinds { margin: 0; }
.studio-kinds .chip { display: inline-flex; align-items: center; gap: 6px; text-decoration: none; }
.studio-week { display: flex; align-items: center; gap: 10px; }
.studio-week strong { min-width: 150px; text-align: center; }
.studio-colours { display: flex; gap: 8px; flex-wrap: wrap; }
.studio-colour { width: 30px; height: 30px; border-radius: 50%; border: 2px solid var(--card); background: var(--c); box-shadow: 0 0 0 1px var(--border); cursor: pointer; padding: 0; }
.studio-colour.active { box-shadow: 0 0 0 3px var(--accent-text); }
.studio-list { display: flex; flex-direction: column; gap: 4px; max-height: 300px; overflow: auto; padding-right: 4px; }
.studio-row { display: flex; align-items: flex-start; gap: 10px; padding: 7px 8px; border-radius: var(--r-sm); cursor: pointer; }
.studio-row:hover { background: var(--surface2); }
.studio-row.off { opacity: .55; }
.studio-row input { margin-top: 3px; }
.studio-row > span:last-child { display: flex; flex-direction: column; min-width: 0; }
.studio-row small { overflow-wrap: anywhere; }
.studio-row > span:last-child > .badge { align-self: flex-start; margin: 2px 0; }
.studio-dot { width: 10px; height: 10px; border-radius: 50%; flex: none; margin-top: 6px; }
.promo-wait { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; gap: 6px; font-weight: 700; color: var(--muted); background: color-mix(in srgb, var(--surface2) 70%, transparent); z-index: 1; }
.promo-size { margin: 8px 0 0; text-align: center; }
.promo-k { margin: 0 0 8px; font-weight: 800; font-size: .9rem; display: flex; align-items: center; gap: 6px; }
.promo-formats { margin: 0; }
.promo-swatches { display: flex; flex-wrap: wrap; gap: 8px; }
.promo-swatch { display: inline-flex; align-items: center; gap: 8px; padding: 6px 12px 6px 6px; border: 1px solid var(--border); border-radius: 999px; background: var(--card); color: var(--ink); font: inherit; font-weight: 700; font-size: .85rem; cursor: pointer; }
.promo-swatch.active { border-color: var(--accent-text); box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent-text) 30%, transparent); }
.promo-swatch-c { width: 26px; height: 26px; border-radius: 50%; border: 1px solid rgba(0,0,0,.12); }
.promo-swatch-navy { background: var(--navy-gradient); }
.promo-swatch-accent { background: linear-gradient(160deg, var(--a), color-mix(in srgb, var(--a) 55%, #000)); }
.promo-swatch-light { background: linear-gradient(180deg, #fff 0 70%, var(--a) 70%); }
.promo-swatch-house { background: radial-gradient(circle at 50% 42%, var(--a) 0 30%, transparent 31%), linear-gradient(180deg, #bcd8ee 0 62%, #f4f0e7 62%); }
/* Board → Visuals (1.50.0, laid out again in 1.50.1): tabs, the preview on
   the left (it stays in view while you scroll the steps), numbered steps on
   the right, one save bar when something changed. */
.vis-tabs { margin: 4px 0 14px; }
.vis-grid { display: grid; grid-template-columns: minmax(0, 380px) minmax(0, 1fr); gap: 18px; align-items: start; }
.vis-preview-col { position: sticky; top: calc(var(--hdr, 0px) + 12px); }
.vis-preview { margin: 0; padding: 14px; }
.vis-preview-bar { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }
.vis-preview-bar select { flex: 1 1 160px; min-width: 0; min-height: 36px; }
.vis-stage { display: flex; justify-content: center; min-width: 0; margin-top: 12px; padding: 12px; border-radius: var(--r-md); background: var(--surface2); }
.vis-stage canvas { display: block; min-width: 0; max-width: 100%; max-height: min(62vh, 560px); width: auto; height: auto; border-radius: 8px; box-shadow: 0 8px 24px rgba(8, 9, 30, .2); }
.vis-stage-note { margin: 10px 2px 0; }
.vis-steps { display: grid; grid-template-columns: minmax(0, 1fr); gap: 14px; min-width: 0; }
.vis-step { margin: 0; }
.vis-step-h { display: flex; align-items: center; gap: 10px; margin: 0 0 6px; font-size: 1.05rem; }
.vis-num { display: inline-flex; align-items: center; justify-content: center; width: 26px; height: 26px; border-radius: 50%; background: var(--esn-dark); color: #fff; font-size: .8rem; font-weight: 900; flex: none; }
.vis-label { font-size: .85rem; font-weight: 700; color: var(--muted); margin: 10px 0 6px; }
.vis-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-top: 12px; }
.vis-row .vis-label { margin: 0; }
.vis-row-wrap { flex-wrap: wrap; justify-content: flex-start; }
.vis-layouts { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 10px; margin-top: 8px; }
.vis-layout { display: flex; flex-direction: column; align-items: center; gap: 4px; padding: 8px 6px 10px; border: 2px solid var(--border); border-radius: var(--r-md); background: var(--card); color: var(--ink); font: inherit; text-align: center; cursor: pointer; }
.vis-layout:hover:not(:disabled) { border-color: color-mix(in srgb, var(--accent-text) 45%, var(--border)); }
.vis-layout.active { border-color: var(--accent-text); box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent-text) 22%, transparent); }
.vis-layout strong { font-size: .85rem; }
.vis-layout small { font-size: .75rem; line-height: 1.3; color: var(--muted); }
.vis-thumb { width: 100%; max-width: 108px; aspect-ratio: 9 / 16; height: auto; border-radius: 8px; background: var(--surface2); }
.vis-drop { display: flex; align-items: center; gap: 14px; padding: 12px; border: 2px dashed var(--border); border-radius: var(--r-md); cursor: pointer; transition: border-color .15s, background .15s; }
.vis-drop:hover, .vis-drop:focus-visible, .vis-drop.is-over { border-color: var(--accent-text); background: color-mix(in srgb, var(--accent-text) 6%, transparent); outline: none; }
.vis-drop.is-busy { opacity: .6; pointer-events: none; }
.vis-drop.is-off { cursor: default; }
.vis-drop-txt { display: grid; gap: 4px; min-width: 0; }
.vis-drop-txt small { font-size: .8rem; color: var(--muted); line-height: 1.4; }
.vis-bg-thumb { width: 64px; height: 114px; border-radius: 10px; overflow: hidden; display: inline-flex; align-items: center; justify-content: center; background: var(--surface2); color: var(--muted); flex: none; }
.vis-bg-thumb img { width: 100%; height: 100%; object-fit: cover; }
.vis-fonts { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
.vis-font { display: grid; gap: 2px; padding: 10px 12px; border: 2px solid var(--border); border-radius: 12px; background: var(--card); color: var(--ink); text-align: left; cursor: pointer; font: inherit; }
.vis-font span { font-size: 1.15rem; font-weight: 700; color: var(--accent-text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.vis-font small { font-size: .75rem; color: var(--muted); }
.vis-font.active { border-color: var(--accent-text); box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent-text) 22%, transparent); }
.vis-switch { display: flex; align-items: flex-start; gap: 12px; cursor: pointer; }
.vis-switch input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.vis-switch-ui { position: relative; flex: none; width: 46px; height: 28px; margin-top: 2px; border-radius: 999px; background: var(--border); transition: background .15s; }
.vis-switch-ui::after { content: ""; position: absolute; top: 3px; left: 3px; width: 22px; height: 22px; border-radius: 50%; background: #fff; box-shadow: 0 1px 3px rgba(0, 0, 0, .3); transition: transform .15s; }
.vis-switch input:checked + .vis-switch-ui { background: var(--esn-green); }
.vis-switch input:checked + .vis-switch-ui::after { transform: translateX(18px); }
.vis-switch input:focus-visible + .vis-switch-ui { outline: 2px solid var(--esn-cyan); outline-offset: 2px; }
.vis-switch input:disabled + .vis-switch-ui { opacity: .5; }
.vis-switch > span:last-child { display: grid; gap: 2px; }
.vis-switch small { font-size: .8rem; color: var(--muted); line-height: 1.4; }
.vis-savebar { margin-top: 14px; }
.vis-savebar .form-hint { margin-right: auto; }
.vis-more { margin-top: 16px; }
.vis-more summary { cursor: pointer; font-weight: 700; }
@media (max-width: 860px) {
  .vis-grid { grid-template-columns: minmax(0, 1fr); }
  .vis-preview-col { position: static; }
  .vis-stage canvas { max-height: 52vh; }
}
@media (max-width: 480px) {
  .vis-layouts { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .vis-fonts { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .vis-row { flex-wrap: wrap; }
}
.promo-toggles { display: flex; flex-wrap: wrap; gap: 6px 18px; }
/* 1.50.3: Promote as one tool: four short sections, the actions and the notes under the preview */
.promo-controls { display: grid; grid-template-columns: minmax(0, 1fr); gap: 12px; min-width: 0; }  /* 1.52.0: an implicit column grew to the widest chip row and pushed the cards past the screen */
.promo-sec { margin: 0; }
.promo-reset { margin-left: auto; }
.promo-layouts { margin: 0 0 8px; }
.promo-notes { display: grid; gap: 6px; margin: 10px 0 0; }
.promo-notes:empty { display: none; }
.promo-fhint { margin: 4px 0 0; }
.promo-notes .material-symbols-rounded { vertical-align: -3px; margin-right: 4px; }
.promo-actions { margin-top: 12px; }
@media (max-width: 860px) {
  .promo { grid-template-columns: minmax(0, 1fr); }
  .promo-preview { position: static; }
}

/* 1.40.0: mobile polish from the September screenshots. The grids that let
   one long word push them past the screen get a real minimum. */
.money-lbl small { display: block; font-size: .75rem; line-height: 1.3; }
.money-lbl small.t-danger { font-weight: 700; }

/* ---------- The dragon runs (1.43.0) ---------- */
/* The dragon runs (1.43.0): the easter egg's canvas. */
.dragon-page { max-width: var(--w-read); margin: 0 auto; }
#dragon-run { margin-top: 12px; }
canvas.dragon-run { display: block; width: 100%; border-radius: var(--r-md); border: 1px solid var(--border, #e3e5f2); touch-action: none; user-select: none; -webkit-user-select: none; -webkit-tap-highlight-color: transparent; cursor: pointer; outline: none; }

/* ---------- The arcade (1.44.0) ---------- */
/* The arcade (1.44.0): the game corner, the full-screen stage, flag match. */
.arcade-pick { margin: 4px 0 6px; flex-wrap: wrap; }
.arcade-pick .chip { text-decoration: none; }
.arcade-blurb { margin: 0 0 8px; }
.arcade-stage { position: relative; }
.arcade-tools { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; margin: 8px 0 0; }
.arcade-stage:fullscreen { background: var(--bg, #fff); display: flex; align-items: stretch; }
.arcade-stage:fullscreen .arcade-box { flex: 1 1 auto; display: flex; }
.arcade-stage:fullscreen canvas.dragon-run { border: 0; border-radius: 0; width: 100% !important; height: 100% !important; }
.arcade-box { touch-action: none; -webkit-tap-highlight-color: transparent; user-select: none; -webkit-user-select: none; }
.fl-head { display: flex; justify-content: space-between; font-weight: 800; font-size: .9rem; margin-bottom: 8px; }
.fl-flag { font-size: 96px; line-height: 1; text-align: center; margin: 10px 0 16px; }
.fl-options { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.fl-opt { min-height: 56px; border-radius: var(--r-md); border: 1px solid var(--border); background: var(--card, #fff); color: inherit; font: inherit; font-weight: 700; font-size: .95rem; padding: 10px 12px; cursor: pointer; }
.fl-opt.right { background: #1f9d55; color: #fff; border-color: #1f9d55; }
.fl-opt.wrong { background: var(--danger); color: #fff; border-color: var(--danger); }
.fl-hint { min-height: 2.6em; margin: 10px 0 0; }
.fl-end { text-align: center; padding: 28px 12px; }
.fl-verdict { margin: 0 0 2px; font-weight: 800; color: var(--muted); font-size: .9rem; text-transform: uppercase; letter-spacing: .04em; }
.fl-streak.hot { color: var(--magenta-deep); }
.fl-bar { height: 4px; border-radius: 2px; background: var(--border); overflow: hidden; margin: 0 0 6px; }
.fl-bar i { display: block; height: 100%; background: var(--cyan-on-dark); transition: width .3s ease; }
.fl-key { display: none; }
@media (hover: hover) and (pointer: fine) { .fl-key { display: inline-block; min-width: 1.3em; margin-right: 8px; padding: 0 4px; border-radius: 6px; font: 700 .7rem/1.5 inherit; border: 1px solid var(--border); color: var(--muted); } }
.fl-in { animation: fl-in .28s cubic-bezier(.2, .8, .2, 1.2) both; }
@keyframes fl-in { from { opacity: 0; transform: scale(.85); } to { opacity: 1; transform: none; } }
.fl-big { font-size: 2rem; font-weight: 900; margin: 0 0 6px; }
@media (max-width: 420px) {
  .fl-flag { font-size: 80px; }
}

/* ---------- Tidy (1.45.0) ---------- */
/* Tidy (1.45.0): the assistant's corrections as a diff. */
.tidy-btn { margin-top: 6px; }
.tidy-card { margin-top: 8px; padding: 10px 12px; border: 1px solid var(--border); border-radius: var(--r-md); background: var(--card); }
.tidy-diff { white-space: pre-wrap; font-size: .9rem; line-height: 1.45; }
.tidy-diff del { background: rgba(220, 53, 69, .16); color: inherit; text-decoration: line-through; border-radius: 3px; }
.tidy-diff ins { background: rgba(31, 157, 85, .18); color: inherit; text-decoration: none; border-radius: 3px; }
.tidy-changes { margin: 8px 0 0; padding-left: 18px; font-size: .85rem; color: var(--muted, inherit); }

/* ============================================================
   UTILITIES
   ============================================================ */

/* ---------- Focus rings ---------- */
.esncard-barcode-btn:focus-visible { outline: 2px solid var(--esn-cyan); outline-offset: 3px; }
.btn:focus-visible, .chip:focus-visible, a:focus-visible, button:focus-visible, summary:focus-visible, [tabindex]:focus-visible,
input:focus-visible, select:focus-visible, textarea:focus-visible {
  /* Two-tone ring (1.1.11): ink ring on a background gap - visible on cyan,
     green and magenta controls in both themes, not just on white. */
  outline: var(--ring);
  outline-offset: 2px;
  box-shadow: var(--ring-gap);
}
input:focus, select:focus, textarea:focus { outline: none; }
/* 1.76.1: the title that takes the focus after a page change (announceRoute) carries no ring: the live region already says where we are, and the ring sat as a black box on the hero cards */
h1[tabindex="-1"]:focus, h2[tabindex="-1"]:focus { outline: none; box-shadow: none; }
.inline-input:focus, select:focus {
  border-color: var(--accent-text);  /* 1.55.0: contrast */
  box-shadow: var(--ring-soft);
}
input:focus-visible, select:focus-visible, textarea:focus-visible {
  outline: none;
  border-color: var(--accent-text);  /* 1.55.0: brand blue (cyan in the dark theme); cyan on white was 2.5:1 */
  box-shadow: var(--ring-soft);
}
.qr-tap:focus-visible { outline: 3px solid var(--esn-cyan); outline-offset: 4px; border-radius: var(--r-sm); }  /* 1.29.2: small app comforts */
canvas.dragon-run:focus-visible { box-shadow: 0 0 0 3px rgba(89, 185, 236, .5); }  /* 1.43.0: The dragon runs */

/* ---------- Utilities (1.29.4) ---------- */
/* Spacing utilities (1.29.4): the inline margins the templates used to
   carry, snapped to a 4px grid. */
/* 1.78.9: --under-bar is set only by the phone rule for the first line under the app bar; unset, each utility keeps its own top margin. Not inherited, so a hint inside that first block keeps its pull-up. */
@property --under-bar { syntax: "*"; inherits: false; }
.m-0 { margin: var(--under-bar, 0) 0 0 !important; }
.mt-1 { margin-top: 4px !important; }
.mt-2 { margin-top: 8px !important; }
.mt-3 { margin-top: 12px !important; }
.mt-4 { margin-top: 16px !important; }
.mb-0 { margin-bottom: 0 !important; }
.mb-2 { margin-bottom: 8px !important; }
.mb-3 { margin-bottom: 12px !important; }
.mb-4 { margin-bottom: 16px !important; }
.pull-up { margin: var(--under-bar, -6px) 0 14px !important; }
.pull-up-sm { margin: var(--under-bar, -4px) 0 10px !important; }
.pointer { cursor: pointer; }
.nowrap { white-space: nowrap; }
.ml-auto { margin-left: auto !important; }
.mt-auto { margin-top: auto !important; }
.tar { text-align: right; }
.tac { text-align: center; }
.t-magenta { color: var(--magenta-text); }
.t-dark { color: var(--accent-text); }
.t-orange { color: var(--orange-text); }
.t-danger { color: var(--danger); }
.t-green { color: var(--green-text); }
.t-muted { color: var(--muted); }

/* 1.46.0: the two widths the admin forms used as inline styles. */
.w-110 { width: 110px; }
.w-170 { width: 170px; }

/* ============================================================
   KEYFRAMES
   ============================================================ */
@keyframes sheet-in { from { transform: translateY(20px); opacity: .6; } }
@keyframes bar-grow { to { transform: scaleY(1); } }
/* motion */
@keyframes line-draw { to { stroke-dashoffset: 0; } }
@keyframes arc-flow { to { stroke-dashoffset: -28; } }
@keyframes globe-ripple { 0% { transform: scale(.4); opacity: .95; } 100% { transform: scale(6); opacity: 0; } }
@keyframes pt-pulse { 0% { transform: scale(.6); opacity: .8; } 100% { transform: scale(2.2); opacity: 0; } }
@keyframes f-unfold { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }
@keyframes spin { to { transform: rotate(360deg); } }
@keyframes cardIntro {
  from { transform: translateY(10px) rotateX(6deg); opacity: 0; }
  to { transform: translateY(0) rotateX(0); opacity: 1; }
}
@keyframes vt-fade-out { from { opacity: 1; } to { opacity: 0; } }
@keyframes vt-rise-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
/* A value the app suggested, briefly highlighted so it reads as a
   suggestion rather than something decided for you (1.1.38). */
@keyframes auto-fill-glow {
  from { background: rgba(0, 174, 239, .22); border-color: var(--esn-cyan); }
  to { background: none; }
}
@media (max-width: 820px) {
  @keyframes page-in {
    from { opacity: .4; transform: translateY(6px); }
    to { opacity: 1; transform: none; }
  }
}
@keyframes checkinPulse {
  0% { transform: scale(.9); opacity: .3; }
  100% { transform: none; opacity: 1; }
}
@keyframes dlgFade { from { opacity: 0; } }
@keyframes dlgFadeOut { to { opacity: 0; } }
/* 1.78.16: the input shake of the transitions library, recreated: 8px, 6px, then back, 280ms */
@keyframes fieldShake { 0% { transform: none; } 28% { transform: translateX(-8px); animation-timing-function: var(--ease-settle); } 57% { transform: translateX(6px); animation-timing-function: var(--ease-settle); } 79% { transform: translateX(-3px); } 100% { transform: none; } }
@keyframes dlgPop { from { transform: translateY(8px) scale(.96); opacity: 0; } to { transform: none; opacity: 1; } }
@keyframes dlgDrop { to { transform: translateY(4px) scale(.96); opacity: 0; } }
@media (max-width: 820px) {
  @keyframes dlgSheet { from { transform: translateY(60%); } to { transform: none; } }
}
@media (max-width: 820px) {
  @keyframes dlgSheetOut { to { transform: translateY(30%); opacity: 0; } }
}
@keyframes toastIn { from { transform: translate(-50%, 16px); opacity: 0; } to { transform: translate(-50%, 0); opacity: 1; } }
@keyframes toastOut { to { transform: translate(-50%, 10px); opacity: 0; } }
@keyframes viewIn { from { opacity: 0; transform: translateY(9px); } to { opacity: 1; transform: none; } }
@keyframes settleIn { from { opacity: .35; transform: translateY(7px); } to { opacity: 1; transform: none; } }  /* 1.69.2: the page's entrance, never from dark */
@keyframes mark-draw { to { stroke-dashoffset: 0; } }
@keyframes mark-pop { 0% { transform: scale(1); } 40% { transform: scale(1.12); } 100% { transform: scale(1); } }
@keyframes livePulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.65; }
}
@keyframes ppGlowPulse {
  0%, 100% { box-shadow: 0 0 0 3px rgba(236, 0, 140, .7), 0 10px 36px rgba(236, 0, 140, .35); }
  50% { box-shadow: 0 0 0 3px rgba(236, 0, 140, .95), 0 12px 46px rgba(236, 0, 140, .55); }
}
@keyframes gnt-sheen { 0% { transform: translateX(0); } 55% { transform: translateX(3400px); } 100% { transform: translateX(3400px); } }
@keyframes gnt-shadow { from { transform: scale(1); } to { transform: scale(.78); opacity: .09; } }
@keyframes gnt-float { from { transform: translateY(0); } to { transform: translateY(-52px); } }
@keyframes gnt-breathe { from { transform: scale(1); } to { transform: scale(1.016); } }
@keyframes gnt-puff  { 0% { opacity: 0; transform: translate(0, 0) scale(.45); } 12% { opacity: .85; } 100% { opacity: 0; transform: translate(-165px, -300px) scale(2.4); } }
@keyframes gnt-puff2 { 0% { opacity: 0; transform: translate(0, 0) scale(.5); }  12% { opacity: .80; } 100% { opacity: 0; transform: translate(-120px, -320px) scale(2.7); } }
@keyframes gnt-puff3 { 0% { opacity: 0; transform: translate(0, 0) scale(.4); }  12% { opacity: .75; } 100% { opacity: 0; transform: translate(-205px, -275px) scale(2.2); } }
@keyframes pp-ring-fill { from { --pp-ring: 0deg; } to { --pp-ring: var(--pp-deg, 0deg); } }
@keyframes pp-pop {
  0% { opacity: 0; transform: scale(.2); }
  100% { opacity: 1; transform: scale(1); }
}
:root[data-cal-swipe="next"] :is(.calendar-grid, .cal-agenda) { animation: cal-in-next .24s cubic-bezier(.2, .7, .3, 1); }  /* 1.69.5: swipe between months (ux.js) */
:root[data-cal-swipe="prev"] :is(.calendar-grid, .cal-agenda) { animation: cal-in-prev .24s cubic-bezier(.2, .7, .3, 1); }
@keyframes cal-in-next { from { opacity: .3; transform: translateX(36px); } }
@keyframes cal-in-prev { from { opacity: .3; transform: translateX(-36px); } }
@keyframes bar-fill { from { transform: translateX(-100%); } }  /* 1.69.5: the bars fill in once when a page arrives */
#app[data-enter] :is(.tp-bar, .pp-badge-bar, .visa-bar, .scan-ev-bar, .join-progress, .pp-quest-bar) i { animation: bar-fill .8s cubic-bezier(.2, .7, .3, 1) .25s backwards; }
@keyframes pp-xp-fill { from { transform: translateX(-100%); } to { transform: translateX(calc(var(--pp-fill, 0%) - 100%)); } }
@keyframes pp-glint { 0% { transform: translateX(-100%); } 55%, 100% { transform: translateX(100%); } }
@keyframes pp-tile-in {
  0% { opacity: 0; transform: translateY(10px) scale(.94); }
  100% { opacity: 1; transform: none; }
}
@keyframes pp-stamp-in {
  0% { opacity: 0; transform: rotate(var(--tilt)) scale(1.55); }
  60% { opacity: 1; transform: rotate(var(--tilt)) scale(.93); }
  100% { opacity: 1; transform: rotate(var(--tilt)) scale(1); }
}
@keyframes pp-shine { 0% { transform: translateX(-120%); } 40%, 100% { transform: translateX(120%); } }
@keyframes pp-badge-pop {
  0% { transform: scale(.7) rotate(-6deg); }
  55% { transform: scale(1.12) rotate(3deg); }
  100% { transform: none; }
}
@keyframes pp-confetti {
  0% { opacity: 1; transform: translate3d(0, 0, 0) rotate(0deg) scale(1); }
  100% { opacity: 0; transform: translate3d(var(--x, 0), var(--y, 0), 0) rotate(var(--r, 360deg)) scale(.4); }
}
@keyframes pp-levelup-in {
  0% { opacity: 0; transform: translate(-50%, -50%) scale(.75); }
  12% { opacity: 1; transform: translate(-50%, -50%) scale(1.04); }
  20% { transform: translate(-50%, -50%) scale(1); }
  82% { opacity: 1; transform: translate(-50%, -50%) scale(1); }
  100% { opacity: 0; transform: translate(-50%, -54%) scale(.96); }
}
@keyframes pp-checkin-win {
  0% { opacity: 0; transform: scale(.82); }
  55% { opacity: 1; transform: scale(1.03); }
  100% { opacity: 1; transform: none; }
}
@keyframes pp-tick {
  0%, 100% { transform: none; }
  20% { transform: scale(1.35) rotate(-8deg); }
  40% { transform: scale(1) rotate(0deg); }
}
@keyframes sm-slam { 0% { transform: rotate(14deg) scale(2.4); opacity: 0; } 60% { transform: rotate(-9deg) scale(.96); opacity: 1; } 100% { transform: rotate(-7deg) scale(1); } }
@keyframes sm-rise { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
@keyframes ppGlowPulseGold { 0%, 100% { box-shadow: 0 0 0 3px rgba(212, 160, 23, .75), 0 10px 36px rgba(212, 160, 23, .35); } 50% { box-shadow: 0 0 0 3px rgba(212, 160, 23, 1), 0 12px 46px rgba(212, 160, 23, .55); } }
@keyframes qrBigIn { from { opacity: 0; transform: scale(.97); } to { opacity: 1; transform: none; } }
@keyframes ptrSpin { to { transform: rotate(360deg); } }
/* Phone: a translucent bar, the active tab an icon in a pill with a filled
   glyph and a bright label; the pill slides to the next tab through the view
   transition (it carries its own name), the tap squeezes it. */
@keyframes vt-slide-out-left { to { opacity: 0; transform: translateX(-18px); } }
@keyframes vt-slide-in-right { from { opacity: 0; transform: translateX(22px); } }
@keyframes vt-slide-out-right { to { opacity: 0; transform: translateX(18px); } }
@keyframes vt-slide-in-left { from { opacity: 0; transform: translateX(-22px); } }
@keyframes vt-push-out { to { opacity: .55; transform: translateX(-10%); } }
@keyframes vt-push-in { from { transform: translateX(100%); box-shadow: -12px 0 30px rgba(0, 0, 0, 0); } to { transform: none; box-shadow: -12px 0 30px rgba(0, 0, 0, .25); } }
@keyframes vt-pop-out { to { transform: translateX(100%); } }
@keyframes vt-pop-in { from { opacity: .55; transform: translateX(-10%); } }

/* 1.53.0: the board archive */
.arc-bar { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin: 4px 0 14px; }
.arc-bar .filter-chips { margin: 0; flex: 1 1 auto; min-width: 0; }
.arc-list { display: grid; gap: 8px; margin: 0 0 18px; }
.arc-card { background: var(--card); border: 1px solid var(--border); border-radius: var(--r-md); padding: 0; min-width: 0; overflow-wrap: anywhere; }
.arc-card > summary { list-style: none; display: flex; align-items: center; gap: 10px; flex-wrap: wrap; padding: 12px 14px; cursor: pointer; }
.arc-card > summary::-webkit-details-marker { display: none; }
.arc-card[open] > summary { border-bottom: 1px solid var(--border); }
.arc-card > :not(summary) { margin-left: 14px; margin-right: 14px; }
.arc-card > :last-child { margin-bottom: 12px; }
.arc-title { display: grid; gap: 1px; flex: 1 1 200px; min-width: 0; }
.arc-v { display: inline-flex; align-items: center; gap: 3px; font-size: .75rem; font-weight: 800; padding: 2px 9px 2px 6px; border-radius: 999px; white-space: nowrap; color: #fff; }
.arc-v .material-symbols-rounded { font-size: 15px; }
.arc-worked { background: #3f8f1f; }
.arc-mixed { background: #c46210; }
.arc-didnt { background: #c0136f; }
.arc-plan { background: #6b7080; } /* 1.54.0: No review, grey: never worked or failed */
.arc-dots { display: inline-flex; gap: 3px; flex-wrap: wrap; max-width: 140px; }
.arc-dot { width: 9px; height: 9px; border-radius: 50%; display: inline-block; }
.arc-rows { list-style: none; padding: 0; margin-top: 10px; display: grid; gap: 8px; }
.arc-rows li { display: flex; gap: 8px; align-items: flex-start; font-size: .9rem; line-height: 1.45; }
.arc-rows li > .arc-v { flex: none; margin-top: 1px; }
.arc-num { font-weight: 700; color: var(--accent-text); }
.arc-lessons { border-left: 3px solid var(--esn-green); padding: 2px 0 2px 10px; margin-top: 10px; font-size: .9rem; }
.arc-lessons ul, .arc-card ul { margin: 4px 0 0; padding-left: 18px; }
.arc-k { margin: 10px 0 0; font-weight: 800; font-size: .85rem; display: flex; align-items: center; gap: 4px; }
.arc-area { display: inline-block; font-size: .75rem; font-weight: 800; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); margin-right: 4px; }
.arc-themes { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 300px), 1fr)); gap: 10px; margin-bottom: 14px; }
.arc-theme { margin: 0; }
.arc-theme ul { margin: 6px 0 0; padding-left: 18px; font-size: .9rem; }
.arc-pick { cursor: pointer; }
#arc-preview .dash-list li > .badge { flex: none; }
/* 1.54.0: today's category on an archive event, the earlier editions card, the timeline, the memory */
.arc-tag { display: inline-flex; align-items: center; gap: 3px; font-size: .75rem; font-weight: 800; padding: 1px 8px 1px 6px; border-radius: 999px; background: color-mix(in srgb, var(--c) 16%, transparent); color: var(--text); border: 1px solid color-mix(in srgb, var(--c) 45%, transparent); vertical-align: middle; white-space: nowrap; }
.arc-tag .material-symbols-rounded { font-size: 14px; color: var(--c); }
.arc-hist { display: grid; gap: 4px; min-width: 0; overflow-wrap: anywhere; }
.arc-hist ul { margin: 2px 0 0; padding-left: 18px; font-size: .9rem; }
.arc-hist-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 10px; }
.arc-years { display: flex; flex-wrap: wrap; gap: 4px; margin: 4px 0; }
.arc-yr { font-size: .75rem; font-weight: 800; color: #fff; padding: 2px 7px; border-radius: 6px; }
.arc-app { list-style: none; padding-left: 0 !important; }
.arc-memo > summary { cursor: pointer; }
.arc-tl { display: grid; gap: 4px; }
.arc-tl-list { list-style: none; margin: 0 0 14px; padding: 0 0 0 14px; border-left: 2px solid var(--border); display: grid; gap: 8px; }
.arc-tl-i { display: flex; gap: 8px; align-items: flex-start; font-size: .9rem; line-height: 1.45; margin-left: -26px; }
.arc-tl-ic { flex: none; width: 24px; height: 24px; border-radius: 50%; display: inline-grid; place-items: center; color: #fff; background: var(--esn-dark); }
.arc-tl-ic .material-symbols-rounded { font-size: 15px; }
.arc-tl-elect .arc-tl-ic { background: #c0136f; }
.arc-tl-mile .arc-tl-ic { background: #c46210; }
.arc-tl-new .arc-tl-ic { background: #3f8f1f; }
.arc-tl-last .arc-tl-ic { background: #6b7080; }
.arc-note { display: flex; gap: 8px; align-items: flex-start; padding: 10px 12px; }
.arc-note-b { flex: 1 1 auto; min-width: 0; display: grid; gap: 4px; }
.arc-note-b .rich p { margin: 0; }
.in-table tr.sel > td { background: var(--hover); }
.in-table tr.sel .card-main strong { color: var(--accent-text); }

/* 1.54.0: rooms. On a laptop the month and the list sit side by side; every
   reservation says what it is for, and one booked with nothing organised is
   marked. */
.rm-sum { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 0 0 14px; }
.rm-pill { display: inline-flex; align-items: center; gap: 5px; padding: 5px 12px; border-radius: 999px; border: 1px solid var(--border); background: var(--card); font-size: .85rem; color: var(--ink); text-decoration: none; box-shadow: inset 3px 0 0 var(--c, transparent); }
.rm-pill-warn { border-color: color-mix(in srgb, var(--esn-orange) 55%, var(--border)); background: color-mix(in srgb, var(--esn-orange) 10%, var(--card)); }
.rm-fresh { margin-left: auto; display: inline-flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.rm-layout { display: grid; grid-template-columns: minmax(0, 1fr); gap: 18px; align-items: start; }
@media (min-width: 1000px) { .rm-layout { grid-template-columns: minmax(0, 1.55fr) minmax(300px, 1fr); } .rm-list { position: sticky; top: calc(var(--hdr, 0px) + 12px); max-height: calc(100vh - var(--hdr, 0px) - 40px); overflow-y: auto; padding-right: 4px; } }
.rm-list .group-title { margin-top: 0; }
.rm-day { margin: 0 0 12px; scroll-margin-top: calc(var(--hdr, 0px) + 16px); }
.rm-date { font-size: .75rem; font-weight: 800; text-transform: uppercase; letter-spacing: .05em; color: var(--muted); margin: 0 0 6px; }
.rm-item { background: var(--card); border: 1px solid var(--border); border-left: 4px solid var(--accent); border-radius: var(--r-md); padding: 10px 12px; margin: 0 0 8px; display: grid; gap: 4px; min-width: 0; overflow-wrap: anywhere; }
.rm-top { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.rm-time { font-weight: 800; font-variant-numeric: tabular-nums; }
.rm-room { font-size: .85rem; color: var(--muted); display: flex; align-items: center; gap: 4px; flex-wrap: wrap; }
.rm-link { display: inline-flex; align-items: center; gap: 6px; font-weight: 700; color: var(--ink); text-decoration: none; padding: 4px 8px; border-radius: var(--r-sm); background: color-mix(in srgb, var(--accent) 12%, var(--card)); width: fit-content; max-width: 100%; flex-wrap: wrap; }
.rm-link .material-symbols-rounded { color: var(--accent); }
.rm-link small { font-weight: 500; color: var(--muted); }
.rm-link:hover { text-decoration: underline; }
.rm-link.rm-day { background: none; padding-left: 0; font-weight: 500; }
.rm-warn { display: inline-flex; align-items: center; gap: 5px; font-size: .85rem; font-weight: 700; color: var(--orange-text, #b45309); }
.rm-chip-warn { outline: 1px dashed var(--esn-orange); }
.rm-chip .material-symbols-rounded { color: var(--esn-orange); }
.rm-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr)); gap: 16px; margin-top: 18px; }
.rm-cards .form-card { margin: 0; scroll-margin-top: calc(var(--hdr, 0px) + 16px); }
.rm-chip .cal-ev-t { white-space: normal; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; line-height: 1.25; }
/* 1.54.0: one colour for every visual, or each event's own */
.vis-colours { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.vis-colour { display: inline-flex; align-items: center; gap: 8px; border: 2px solid var(--border); background: var(--card); color: var(--ink); border-radius: 999px; padding: 4px; font: inherit; font-size: .85rem; font-weight: 700; cursor: pointer; }
.vis-colour > span { width: 26px; height: 26px; border-radius: 50%; background: var(--c); display: inline-block; }
.vis-colour-event { padding-right: 12px; }
.vis-colour-event > span { background: conic-gradient(#00AEEF 0 25%, #EC008C 0 50%, #7AC143 0 75%, #F47B20 0); }
.vis-colour.active { border-color: var(--accent-text); box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent-text) 30%, transparent); }
.vis-colour:disabled { cursor: default; opacity: .7; }

/* ---------- The website report, set up before copying (1.56.0) ---------- */
/* 1.56.5: a board page (/board/website), no longer a dialog */
.rc-grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: 20px; margin-top: 4px; }
@media (min-width: 900px) { .rc-grid { grid-template-columns: 340px minmax(0, 1fr); gap: 24px; } }
.rc-form .seg { max-width: 100%; }
.rc-part { margin: 6px 0; align-items: flex-start; }
.rc-part .form-hint { font-weight: 500; }
.rc-inline { display: flex; align-items: center; gap: 8px; margin-top: 8px; font-size: .85rem; }
.rc-inline input[type="number"] { width: 120px; }
.rc-where { margin-top: 6px; }
.rc-swatches { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.rc-swatch { width: 32px; height: 32px; border-radius: 50%; border: 2px solid var(--border); background: var(--surface2); color: var(--muted); display: grid; place-items: center; cursor: pointer; padding: 0; }
.rc-swatch.active { border-color: var(--ink); box-shadow: 0 0 0 2px var(--card), 0 0 0 4px var(--accent-text); }
.rc-swatches input[type="color"], .rc-inline input[type="color"], .rc-hostbg input[type="color"] { width: 36px; height: 32px; padding: 2px; border: 1px solid var(--border); border-radius: 8px; background: var(--card); cursor: pointer; }
.rc-hostbg { display: inline-flex; align-items: center; gap: 6px; margin: 0; }
.rc-preview { min-width: 0; display: flex; flex-direction: column; gap: 10px; }
@media (min-width: 900px) { .rc-preview { position: sticky; top: calc(var(--hdr, 0px) + 12px); align-self: start; } }
.rc-bar { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px; }
.rc-stagebox { background: #ffffff; border: 1px solid var(--border); border-radius: var(--r-md); padding: 12px; display: flex; justify-content: center; }
.rc-scaler { position: relative; overflow: hidden; border-radius: 12px; max-width: 100%; }
.rc-frame { display: block; width: 1200px; height: 760px; border: 0; background: transparent; transform-origin: 0 0; }
.rc-frame.phone { width: 390px; max-width: 100%; height: min(62vh, 640px); border-radius: 12px; }
.rc-form .checkbox-row, .rc-form .seg-opt > span { text-transform: none; letter-spacing: 0; }
/* 1.56.6: the choices as separate pills that wrap cleanly in the narrow column, room between the fields */
.rc-form { display: flex; flex-direction: column; gap: 12px; min-width: 0; }
.rc-form .form-field { margin: 0; }
.rc-form .seg { display: flex; flex-wrap: wrap; gap: 6px; border: 0; border-radius: 0; overflow: visible; background: none; }
.rc-form .seg-opt > span { border: 1px solid var(--border); border-radius: 999px; min-height: 36px; padding: 7px 13px; background: var(--card); }
.rc-form .seg-opt:last-child > span { border-right: 1px solid var(--border); }
.rc-form .seg-opt input:checked + span { border-color: var(--esn-dark); }
.rc-form .filter-chips { flex-wrap: wrap; overflow: visible; }
.rc-form .rc-sub { margin: -2px 0 2px; }
@media (max-width: 899px) { .rc-preview { order: -1; } }
.rc-form .checkbox-row { font-weight: 500; }
.rc-code { width: 100%; font: .75rem/1.5 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; resize: vertical; padding: 12px 14px; border-radius: 12px; border: 1px solid var(--border); background: var(--surface2); color: var(--ink); }
/* 1.57.0: the page in three steps: where it goes, make it fit, copy the code */
.rc-page { display: flex; flex-direction: column; gap: 16px; }
.rc-page > .form-card { margin: 0; }
.wk-top { display: flex; flex-direction: column; gap: 6px; padding: 4px 2px 0; }
.wk-top h2 { display: flex; align-items: center; gap: 8px; }
.wk-top .form-hint { max-width: 80ch; }
.wk-step { display: flex; flex-direction: column; gap: 14px; }
.wk-step-h { display: flex; align-items: flex-start; gap: 12px; }
.wk-step-h h3 { font-size: 1.05rem; }
.wk-n { flex: none; display: grid; place-items: center; width: 30px; height: 30px; border-radius: 50%; background: var(--esn-dark); color: #fff; font-weight: 900; font-size: .9rem; }
.wk-places { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 210px), 1fr)); gap: 8px; }
.wk-place { display: flex; align-items: center; gap: 10px; min-height: 60px; padding: 10px 12px; border-radius: var(--r-md); border: 1px solid var(--border); background: var(--surface2); color: var(--ink); font: inherit; text-align: left; cursor: pointer; transition: border-color .15s ease, background .15s ease, transform .15s ease; }
.wk-place:hover { border-color: var(--accent-text); transform: translateY(-1px); }
.wk-place:focus-visible { outline: 2px solid var(--esn-cyan); outline-offset: 2px; }
.wk-place.active { border-color: var(--esn-dark); background: color-mix(in srgb, var(--esn-dark) 16%, var(--card)); box-shadow: inset 0 0 0 1px var(--esn-dark); }
.wk-ic { flex: none; display: grid; place-items: center; width: 38px; height: 38px; border-radius: 12px; background: color-mix(in srgb, var(--esn-cyan) 16%, transparent); color: var(--accent-text); }
.wk-place.active .wk-ic { background: var(--esn-dark); color: #fff; }
.wk-pl { display: flex; flex-direction: column; min-width: 0; }
.wk-pl strong { font-size: .9rem; line-height: 1.25; }
.wk-pl small { font-size: .75rem; color: var(--muted); }
.wk-group { display: flex; flex-direction: column; gap: 14px; padding: 14px; border-radius: var(--r-md); border: 1px solid var(--border); background: var(--surface2); }
.wk-group-h { margin: 0; display: flex; align-items: center; gap: 7px; font-size: .8rem; font-weight: 900; letter-spacing: .08em; text-transform: uppercase; color: var(--ink); }
.wk-bar-r { display: inline-flex; align-items: center; gap: 10px; }
.wk-cap { text-align: center; }
.wk-help { border-top: 1px solid var(--border); padding-top: 10px; }
.wk-help summary { cursor: pointer; font-weight: 800; display: inline-flex; align-items: center; gap: 6px; min-height: 32px; }
.wk-help ol { margin: 8px 0 8px 20px; padding: 0; display: grid; gap: 4px; font-size: .9rem; }
@media (max-width: 559px) { .wk-places { grid-template-columns: repeat(2, minmax(0, 1fr)); } .wk-place { flex-direction: column; align-items: flex-start; gap: 6px; padding: 10px; } .wk-ic { width: 32px; height: 32px; border-radius: 10px; } }
.wk-mini { flex-direction: row; flex-wrap: wrap; align-items: center; justify-content: space-between; }

/* ---------- 1.58.0: claiming a ticket someone sent you ---------- */
.claim-panel { max-width: 460px; margin: 18px auto 0; padding: 22px 20px; border-radius: var(--r-lg); background: var(--card); border: 1px solid var(--border); box-shadow: var(--shadow); display: flex; flex-direction: column; gap: 16px; }
.claim-kicker { margin: 0; display: inline-flex; align-items: center; gap: 6px; font-weight: 800; font-size: .85rem; color: var(--accent-text); }
.claim-ev { display: grid; grid-template-columns: 72px minmax(0, 1fr); gap: 14px; align-items: center; }
.claim-ev h1 { font-size: 1.3rem; line-height: 1.2; overflow-wrap: anywhere; }
.claim-img { width: 72px; height: 72px; border-radius: var(--r-md); object-fit: cover; }
.claim-ic { width: 72px; height: 72px; border-radius: var(--r-md); display: grid; place-items: center; color: #fff; background: var(--c, var(--esn-dark)); }
.claim-ic .material-symbols-rounded { font-size: 32px; }
.claim-steps { list-style: none; margin: 0; padding: 12px 14px; border-radius: var(--r-md); background: var(--surface2); display: flex; flex-direction: column; gap: 8px; font-size: .9rem; }
.claim-steps li { display: flex; gap: 8px; align-items: flex-start; }
.claim-steps li > span:last-child { flex: 1; min-width: 0; }
.claim-steps .material-symbols-rounded { color: var(--muted); margin-top: 1px; }
.claim-acts { display: flex; flex-direction: column; gap: 8px; }

/* ---- 1.63.0: the SumUp Solo on the Cloud API (reader.js) ---- */
.checkin-panel .solo-btn { margin: 8px 0 0 8px; }
.solo-sheet { width: min(440px, 100%); }
.solo-head { display: flex; flex-direction: column; gap: 2px; margin-bottom: 12px; }
.solo-head strong { font-size: 1.05rem; }
.solo-state { display: flex; flex-direction: column; align-items: center; gap: 4px; padding: 18px 8px; text-align: center; border-radius: var(--r-md); background: var(--bg); }
.solo-state .material-symbols-rounded { font-size: 2.8rem; }
.solo-state strong { font-size: 1.15rem; }
.solo-state small { color: var(--muted); font-size: .85rem; }
.solo-state.good { color: var(--green-text, var(--esn-green)); }
.solo-state.bad { color: var(--esn-magenta); }
.solo-state.wait .material-symbols-rounded { color: var(--esn-cyan); animation: soloPulse 1.4s ease-in-out infinite; }
@keyframes soloPulse { 50% { opacity: .35; } }
.solo-actions { flex-wrap: wrap; }
.solo-readers { display: grid; gap: 8px; margin: 10px 0; }
.solo-reader { display: flex; justify-content: space-between; align-items: center; gap: 8px; min-height: 48px; padding: 8px 12px; border: 1px solid var(--border); border-radius: var(--r-md); background: var(--card); color: var(--ink); font: inherit; text-align: left; cursor: pointer; }
.solo-reader.sel { border-color: var(--esn-cyan); box-shadow: 0 0 0 2px var(--esn-cyan); }
.solo-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
.solo-list > li { display: flex; justify-content: space-between; align-items: center; gap: 8px; flex-wrap: wrap; padding: 8px 0; border-bottom: 1px solid var(--border); }
.solo-row-actions { display: flex; gap: 6px; flex-wrap: wrap; }
.solo-steps { padding-left: 20px; }

/* ---- 1.64.0: the Payment Terminal (reader.js, /terminal and /board/terminal) ---- */
.pos-head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 10px; margin: 28px 0 12px; }
.pos-status { display: flex; flex-wrap: wrap; gap: 8px; }
.pos-chip { display: inline-flex; align-items: center; gap: 6px; min-height: 38px; padding: 4px 12px; border: 1px solid var(--border); border-radius: 999px; background: var(--card); color: var(--ink); font: inherit; font-size: .85rem; font-weight: 700; text-decoration: none; cursor: pointer; }
.pos-chip select { border: 0; background: transparent; color: inherit; font: inherit; max-width: 210px; padding: 0; min-height: 0; }
.pos-chip-off { color: var(--muted); cursor: default; }
.pos-kp input, .pos-cash-chips input, .posa-fields input, .posa-fields select { padding: 8px 12px; border: 1px solid var(--border); border-radius: var(--r-sm); background: var(--card); color: var(--ink); font-family: inherit; font-size: .95rem; }
.pos-kp input:focus, .pos-cash-chips input:focus, .posa-fields input:focus, .posa-fields select:focus { outline: none; border-color: var(--accent-text); box-shadow: var(--ring-soft); }
.pos-status a.pos-chip { color: var(--ink); }
.pos-dot { width: 9px; height: 9px; border-radius: 50%; background: var(--muted); }
.pos-dot.on { background: var(--esn-green); box-shadow: 0 0 0 3px rgba(122, 193, 67, .25); }
.pos-dot.off { background: var(--esn-magenta); }
.pos-seg { display: inline-flex; gap: 4px; padding: 4px; margin-bottom: 14px; border: 1px solid var(--border); border-radius: 999px; background: var(--bg); }
.pos-seg button { display: inline-flex; align-items: center; gap: 6px; min-height: 38px; padding: 4px 16px; border: 0; border-radius: 999px; background: transparent; color: var(--muted); font: inherit; font-weight: 700; cursor: pointer; }
.pos-seg button[aria-selected="true"] { background: var(--card); color: var(--ink); box-shadow: 0 1px 4px rgba(8, 9, 30, .14); }
.pos-badge { min-width: 20px; padding: 0 6px; border-radius: 10px; background: var(--esn-cyan); color: var(--on-bright); font-size: .75rem; text-align: center; }
.pos-badge:empty { display: none; }
.pos-main { display: grid; grid-template-columns: minmax(0, 1fr) 340px; gap: 18px; align-items: start; }
.pos-main[hidden], .pos-today[hidden] { display: none; }
.pos-cats { display: flex; gap: 8px; overflow-x: auto; scrollbar-width: none; padding-bottom: 4px; margin-bottom: 12px; }
.pos-cats .chip { flex: none; min-height: 38px; }
.pos-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(136px, 1fr)); gap: 12px; }
.pos-item { position: relative; display: flex; flex-direction: column; gap: 6px; padding: 8px 8px 10px; border: 1px solid var(--border); border-radius: var(--r-md); background: var(--card); color: var(--ink); font: inherit; text-align: left; cursor: pointer; touch-action: manipulation; -webkit-tap-highlight-color: transparent; transition: border-color .15s, box-shadow .15s; }
.pos-item:hover { border-color: var(--esn-cyan); }
.pos-item.in { border-color: var(--esn-cyan); box-shadow: 0 0 0 2px var(--esn-cyan); }
.pos-item.tap { animation: posTap .18s ease-out; }
@keyframes posTap { 50% { transform: scale(.95); } }
.pos-pic { display: grid; place-items: center; aspect-ratio: 1; border-radius: var(--r-sm); overflow: hidden; background: hsl(var(--h, 200) 62% 92%); color: hsl(var(--h, 200) 45% 32%); }
html[data-theme="dark"] .pos-pic { background: hsl(var(--h, 200) 28% 22%); color: hsl(var(--h, 200) 60% 80%); }
.pos-pic img { width: 100%; height: 100%; object-fit: cover; }
.pos-pic b { font-size: 2rem; font-weight: 900; }
.pos-pic .material-symbols-rounded { font-size: 2rem; }
.pos-name { font-size: .95rem; font-weight: 700; line-height: 1.2; overflow-wrap: anywhere; }
.pos-price { font-size: .9rem; color: var(--muted); font-variant-numeric: tabular-nums; }
.pos-price s { opacity: .7; }
.pos-q { position: absolute; top: 4px; right: 4px; display: grid; place-items: center; min-width: 30px; height: 30px; padding: 0 8px; border-radius: 15px; background: var(--esn-cyan); color: var(--on-bright); font-size: .95rem; font-weight: 900; box-shadow: 0 2px 8px rgba(8, 9, 30, .25); }
.pos-typed { border-style: dashed; }
.pos-typed .pos-pic { background: var(--bg); color: var(--muted); }
.pos-empty { grid-column: 1 / -1; }
.pos-cart { position: sticky; top: 76px; display: flex; flex-direction: column; gap: 12px; max-height: calc(100vh - 96px); overflow: auto; padding: 16px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--card); box-shadow: var(--shadow-lg); }
.pos-cart-head { display: flex; justify-content: space-between; align-items: center; }
.pos-cart-head strong { font-size: 1.15rem; }
.pos-x { display: none; place-items: center; width: 38px; height: 38px; border: 0; border-radius: 50%; background: var(--bg); color: var(--ink); cursor: pointer; }
.pos-member { display: grid; grid-template-columns: auto 1fr; gap: 0 10px; align-items: center; padding: 10px 12px; border-radius: var(--r-sm); background: var(--bg); cursor: pointer; }
.pos-member span { font-weight: 700; }
.pos-member small { grid-column: 2; color: var(--muted); font-size: .75rem; }
.pos-member input { width: 20px; height: 20px; grid-row: span 2; }
.pos-lines { list-style: none; margin: 0; padding: 0; }
.pos-lines > li { display: grid; grid-template-columns: minmax(0, 1fr) auto auto; gap: 8px; align-items: center; padding: 8px 0; border-bottom: 1px solid var(--border); font-size: .95rem; }
.pos-l-name { overflow-wrap: anywhere; }
.pos-l-sum { min-width: 70px; text-align: right; font-weight: 700; font-variant-numeric: tabular-nums; }
.pos-step { display: inline-flex; align-items: center; gap: 6px; }
.pos-step b { min-width: 18px; text-align: center; }
.pos-step button { display: grid; place-items: center; width: 34px; height: 34px; border: 1px solid var(--border); border-radius: 50%; background: var(--card); color: var(--ink); cursor: pointer; touch-action: manipulation; }
.pos-hint { display: flex; flex-direction: column; align-items: center; gap: 6px; margin: 0; padding: 18px 0; color: var(--muted); text-align: center; }
.pos-total { display: flex; justify-content: space-between; align-items: baseline; padding-top: 10px; border-top: 2px solid var(--border); }
.pos-total strong { font-size: 1.7rem; font-variant-numeric: tabular-nums; }
.pos-pay { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); gap: 8px; }
.pos-paybtn { min-height: 58px; font-size: 1.05rem; justify-content: center; gap: 8px; }
.pos-clear { align-self: center; }
.pos-bar { display: none; }
.pos-kp-card { width: min(380px, 100%); }
.pos-kp, .pos-cashs { display: flex; flex-direction: column; gap: 12px; }
.pos-kp-show { padding: 4px 0; font-size: 2.4rem; font-weight: 900; text-align: center; font-variant-numeric: tabular-nums; }
.pos-kp-keys { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
.pos-kp-keys button { min-height: 58px; border: 1px solid var(--border); border-radius: var(--r-md); background: var(--bg); color: var(--ink); font: inherit; font-size: 1.45rem; font-weight: 700; cursor: pointer; touch-action: manipulation; }
.pos-kp-keys button:active { background: var(--border); }
.pos-cash-chips { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.pos-cash-chips .chip { min-height: 40px; }
.pos-cash-chips input { width: 104px; min-height: 40px; }
.pos-change { padding: 12px; border-radius: var(--r-sm); background: var(--bg); font-size: 1.05rem; text-align: center; }
.pos-change.give { background: rgba(122, 193, 67, .16); color: var(--green-text); }
.pos-change.give strong { font-size: 1.3rem; }
.pos-change.short { color: var(--esn-magenta); }
.pos-flash { position: fixed; left: 50%; top: 42%; z-index: 260; display: flex; flex-direction: column; align-items: center; gap: 6px; padding: 22px 30px; border-radius: 22px; background: var(--esn-green); color: var(--on-bright); box-shadow: 0 24px 60px rgba(8, 9, 30, .38); pointer-events: none; animation: posFlash 1.6s ease forwards; }
.pos-flash.card { background: var(--esn-cyan); }
.pos-flash .material-symbols-rounded { font-size: 2.8rem; }
.pos-flash strong { font-size: 1.15rem; }
@keyframes posFlash { 0% { opacity: 0; transform: translate(-50%, -40%) scale(.9); } 12% { opacity: 1; transform: translate(-50%, -50%) scale(1); } 80% { opacity: 1; transform: translate(-50%, -50%); } 100% { opacity: 0; transform: translate(-50%, -55%); } }
.pos-tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 10px; margin-bottom: 8px; }
.pos-tile { display: flex; flex-direction: column; gap: 2px; padding: 12px 14px; border: 1px solid var(--border); border-radius: var(--r-md); background: var(--card); }
.pos-tile strong { font-size: 1.45rem; font-variant-numeric: tabular-nums; }
.pos-tile small, .pos-tile span { color: var(--muted); font-size: .8rem; }
.pos-sales { list-style: none; margin: 0 0 12px; padding: 0; border: 1px solid var(--border); border-radius: var(--r-md); background: var(--card); }
.pos-sales > li { display: grid; grid-template-columns: 52px minmax(0, 1fr) auto auto; gap: 10px; align-items: center; padding: 10px 12px; border-bottom: 1px solid var(--border); }
.pos-sales > li:last-child { border-bottom: 0; }
.pos-s-time { color: var(--muted); font-size: .85rem; font-variant-numeric: tabular-nums; }
.pos-s-what strong { font-size: .95rem; overflow-wrap: anywhere; }
.pos-s-what small { display: block; color: var(--muted); font-size: .8rem; }
.pos-s-sum { font-weight: 700; font-variant-numeric: tabular-nums; }
.pos-sales > li.void .pos-s-what strong, .pos-sales > li.void .pos-s-sum { text-decoration: line-through; opacity: .55; }
.posa-head { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: flex-start; gap: 12px; margin: 20px 0 14px; }
.posa-head .form-hint { max-width: 640px; }
.posa-cats { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.posa-cat { display: inline-flex; align-items: center; gap: 2px; }
.posa-ic { display: grid; place-items: center; width: 34px; height: 34px; border: 1px solid var(--border); border-radius: var(--r-sm); background: var(--card); color: var(--ink); cursor: pointer; }
.posa-ic.danger { color: var(--esn-magenta); }
.posa-group { margin: 18px 0; }
.posa-ghead { display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px; }
.posa-ghead h3 { margin: 0; font-size: 1.15rem; }
.posa-row { display: grid; grid-template-columns: 76px minmax(0, 1fr) auto; gap: 12px; align-items: center; margin-bottom: 8px; padding: 10px; border: 1px solid var(--border); border-radius: var(--r-md); background: var(--card); }
.posa-row.off { opacity: .6; }
.posa-pic { position: relative; display: grid; place-items: center; width: 76px; height: 76px; border: 1px dashed var(--border); border-radius: var(--r-sm); overflow: hidden; background: hsl(var(--h, 200) 62% 92%); color: hsl(var(--h, 200) 45% 32%); cursor: pointer; }
html[data-theme="dark"] .posa-pic { background: hsl(var(--h, 200) 28% 22%); color: hsl(var(--h, 200) 60% 80%); }
.posa-pic img { width: 100%; height: 100%; object-fit: cover; }
.posa-pic.busy { opacity: .45; pointer-events: none; }
.posa-fields { display: grid; grid-template-columns: minmax(150px, 2fr) minmax(0, 1fr) minmax(0, 1fr) minmax(120px, 1fr); gap: 8px; align-items: end; }
.posa-fields input, .posa-fields select { width: 100%; min-height: 40px; }
.posa-fields input.bad { border-color: var(--esn-magenta); }
.posa-money { display: flex; flex-direction: column; gap: 2px; }
.posa-money span { color: var(--muted); font-size: .75rem; font-weight: 700; text-transform: uppercase; }
.posa-acts { display: flex; flex-wrap: wrap; justify-content: flex-end; align-items: center; gap: 6px; }
.posa-on { display: inline-flex; align-items: center; gap: 6px; font-size: .85rem; }
.posa-save { position: sticky; bottom: 16px; z-index: 60; display: flex; align-items: center; gap: 10px; padding: 10px 14px; border: 1px solid var(--border); border-radius: var(--r-md); background: var(--card); box-shadow: var(--shadow-lg); }
.posa-save[hidden] { display: none; }
.posa-save > span { margin-right: auto; font-weight: 700; }
@media (max-width: 899px) {
  .pos-main { grid-template-columns: minmax(0, 1fr); padding-bottom: 8px; }
  .pos-grid { grid-template-columns: repeat(auto-fill, minmax(104px, 1fr)); gap: 10px; }
  .pos-cart { position: fixed; top: auto; left: 0; right: 0; bottom: 0; z-index: 215; max-height: 84vh; border-radius: 18px 18px 0 0; transform: translateY(105%); transition: transform .22s ease; }
  .pos.cart-open .pos-cart { transform: none; }
  .pos.cart-open::before { content: ""; position: fixed; inset: 0; z-index: 210; background: rgba(15, 16, 40, .5); }
  .pos-x { display: grid; }
  .pos-bar { position: sticky; bottom: calc(var(--bottom-nav, 64px) + 10px); z-index: 50; display: block; margin-top: 14px; }
  .pos-bar-btn { display: flex; align-items: center; justify-content: space-between; gap: 10px; width: 100%; min-height: 58px; padding: 8px 18px; border: 0; border-radius: 16px; background: var(--esn-cyan); color: var(--on-bright); font: inherit; font-weight: 700; box-shadow: 0 10px 26px rgba(8, 9, 30, .28); cursor: pointer; }
  .pos-bar-btn strong { font-size: 1.3rem; font-variant-numeric: tabular-nums; }
  .pos-bar-go { display: inline-flex; align-items: center; }
  .pos-sales > li { grid-template-columns: 44px minmax(0, 1fr) auto; }
  .pos-undo { grid-column: 2 / -1; justify-self: start; }
  .posa-row { grid-template-columns: 64px minmax(0, 1fr); }
  .posa-pic { width: 64px; height: 64px; }
  .posa-fields { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .posa-name { grid-column: 1 / -1; }
  .posa-acts { grid-column: 1 / -1; justify-content: flex-start; }
  .posa-save { bottom: calc(var(--bottom-nav, 64px) + 10px); }
  .pos-products { padding-bottom: 4px; }
}

/* ---- 1.65.0: the shop (shop.js): grid, product, basket; order lines ---- */
.sh-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; margin: 28px 0 4px; }
.sh-sub { margin: 0 0 14px; }
.sh-basket { position: relative; display: inline-flex; align-items: center; gap: 6px; min-height: 38px; }
.sh-basket.bump { animation: shBump .4s ease; }
@keyframes shBump { 30% { transform: scale(1.12); } }
.sh-badge { min-width: 20px; height: 20px; padding: 0 6px; border-radius: 10px; background: var(--esn-magenta); color: #fff; font-size: .75rem; font-weight: 900; display: inline-grid; place-items: center; }
.sh-badge:empty { display: none; }
.sh-cardtile { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: 12px; align-items: center; margin: 0 0 16px; padding: 12px 14px; border: 1px solid var(--border); border-left: 4px solid var(--esn-cyan); border-radius: var(--r-md); background: var(--card); }
.sh-cardtile > div:first-child .material-symbols-rounded { font-size: 2rem; color: var(--esn-cyan); }
.sh-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 16px; }
.sh-card { position: relative; display: flex; flex-direction: column; border: 1px solid var(--border); border-radius: var(--radius); background: var(--card); overflow: hidden; box-shadow: var(--shadow); transition: box-shadow .2s, transform .2s; cursor: pointer; animation: viewIn .34s ease backwards; }
.sh-card:hover { box-shadow: var(--shadow-lg); transform: translateY(-2px); }
.sh-card:has(.card-link:focus-visible) { outline: var(--ring); outline-offset: 2px; }
.sh-card.gone .sh-card-media img { filter: grayscale(.6); opacity: .7; }
.sh-card-media { position: relative; aspect-ratio: 1; overflow: hidden; background: color-mix(in srgb, var(--accent, var(--esn-cyan)) 14%, var(--card)); display: grid; place-items: center; }
.sh-card-media img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; transition: opacity .3s; }
.sh-card-media .sh-card-alt { opacity: 0; }
.sh-card:hover .sh-card-media .sh-card-alt { opacity: 1; }
.sh-card-ph .material-symbols-rounded { font-size: 64px; opacity: .7; }
.sh-flag { position: absolute; left: 10px; top: 10px; padding: 3px 9px; border-radius: 999px; font-size: .75rem; font-weight: 900; text-transform: uppercase; letter-spacing: .3px; }
.sh-flag.out { background: var(--esn-dark); color: #fff; }
.sh-flag.low { background: var(--esn-orange); color: var(--on-bright); }
.sh-card-body { display: flex; flex-direction: column; gap: 6px; padding: 12px 14px 14px; }
.sh-card-body h3 { margin: 0; font-size: 1rem; font-weight: 900; line-height: 1.3; }
.sh-card-body h3 a { color: var(--ink); text-decoration: none; }
.sh-card-blurb { margin: 0; font-size: .8rem; color: var(--muted); display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; }
.sh-card-price { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; margin-top: auto; font-variant-numeric: tabular-nums; }
.sh-card-price strong { font-size: 1.05rem; }
.sh-swatches { display: flex; align-items: center; gap: 5px; }
.sh-swatches small { color: var(--muted); font-size: .75rem; }
.sh-swatch { display: inline-grid; place-items: center; width: 26px; height: 26px; border-radius: 50%; background: var(--sw, #c9ccd6); border: 1px solid rgba(0, 0, 0, .14); overflow: hidden; box-shadow: inset 0 0 0 2px var(--card); }
.sh-swatch.xs { width: 16px; height: 16px; box-shadow: none; }
.sh-swatch img { width: 100%; height: 100%; object-fit: cover; }
.sh-crumb { justify-content: space-between; }
.sh-gallery { display: flex; flex-direction: column; gap: 10px; }
.sh-main { position: relative; aspect-ratio: 1; border-radius: var(--radius); overflow: hidden; border: 1px solid var(--border); background: var(--card); display: grid; place-items: center; }
.sh-main img { width: 100%; height: 100%; object-fit: cover; display: block; }
.sh-noimg .material-symbols-rounded { font-size: 72px; color: var(--muted); }
.sh-nav { position: absolute; top: 50%; transform: translateY(-50%); display: grid; place-items: center; width: 40px; height: 40px; border: 0; border-radius: 50%; background: rgba(255, 255, 255, .9); color: #12142a; cursor: pointer; box-shadow: 0 2px 8px rgba(0, 0, 0, .2); }
.sh-nav.prev { left: 10px; }
.sh-nav.next { right: 10px; }
.sh-count { position: absolute; right: 10px; bottom: 10px; padding: 2px 8px; border-radius: 999px; background: rgba(18, 20, 42, .7); color: #fff; font-size: .75rem; font-weight: 700; }
.sh-thumbs { display: flex; gap: 8px; overflow-x: auto; scrollbar-width: none; padding: 2px; }
.sh-thumbs button { flex: none; width: 64px; height: 64px; padding: 0; border: 2px solid transparent; border-radius: var(--r-sm); overflow: hidden; background: var(--card); cursor: pointer; }
.sh-thumbs button.sel { border-color: var(--esn-cyan); }
.sh-thumbs img { width: 100%; height: 100%; object-fit: cover; display: block; }
.sh-colors { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 4px; }
.sh-color { position: relative; display: grid; place-items: center; width: 40px; height: 40px; padding: 0; border: 2px solid transparent; border-radius: 50%; background: transparent; cursor: pointer; }
.sh-color.sel { border-color: var(--esn-dark); }
html[data-theme="dark"] .sh-color.sel { border-color: var(--esn-cyan); }
.sh-color.gone { opacity: .4; }
.sh-color.gone::after { content: ""; position: absolute; width: 36px; height: 2px; background: var(--ink); transform: rotate(-45deg); }
.sh-sizes .chip[aria-disabled="true"] { opacity: .45; text-decoration: line-through; }
.sh-sizes .chip small { font-weight: 500; color: var(--muted); }  /* 1.78.4: was opacity .8 */
.sh-full { color: var(--muted); font-size: .95rem; }
.sh-qtyrow { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.sh-sticky { display: none; }
.sh-cart { max-width: var(--w-wide); margin: 0 auto; }
.sh-cart-grid { display: grid; grid-template-columns: minmax(0, 1.4fr) minmax(280px, 1fr); gap: 20px; align-items: start; }
.sh-lines { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.sh-line { display: grid; grid-template-columns: 72px minmax(0, 1fr) auto auto; gap: 12px; align-items: center; padding: 10px; border: 1px solid var(--border); border-radius: var(--r-md); background: var(--card); }
.sh-line-pic { display: grid; place-items: center; width: 72px; height: 72px; border-radius: var(--r-sm); overflow: hidden; background: var(--bg); color: var(--muted); }
.sh-line-pic img { width: 100%; height: 100%; object-fit: cover; }
.sh-line-main { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.sh-line-main a { color: var(--ink); text-decoration: none; }
.sh-line-main small { color: var(--muted); font-size: .8rem; }
.sh-line-qty input { width: 44px; }
.sh-line-sum { min-width: 70px; text-align: right; font-variant-numeric: tabular-nums; }
.sh-summary { position: sticky; top: 76px; display: flex; flex-direction: column; gap: 12px; padding: 16px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--card); box-shadow: var(--shadow); }
.sh-code label { display: block; font-size: .8rem; font-weight: 700; color: var(--muted); text-transform: uppercase; letter-spacing: .4px; margin-bottom: 4px; }
.sh-code-row { display: flex; gap: 6px; }
.sh-code-row input { flex: 1; min-width: 0; min-height: 40px; padding: 8px 12px; border: 1px solid var(--border); border-radius: var(--r-sm); background: var(--card); color: var(--ink); font: inherit; text-transform: uppercase; }
.sh-code-row input:focus { outline: none; border-color: var(--accent-text); box-shadow: var(--ring-soft); }
.sh-code small { display: block; margin-top: 4px; font-size: .8rem; }
.sh-totals { display: grid; grid-template-columns: 1fr auto; gap: 6px 10px; margin: 0; padding-top: 10px; border-top: 1px solid var(--border); font-variant-numeric: tabular-nums; }
.sh-totals dd { margin: 0; text-align: right; }
.sh-totals .sh-total { font-size: 1.3rem; font-weight: 900; padding-top: 4px; }
.order-lines { list-style: none; margin: 0 0 10px; padding: 0; display: flex; flex-direction: column; gap: 6px; text-align: left; }
.order-lines > li { display: grid; grid-template-columns: 44px minmax(0, 1fr) auto; gap: 10px; align-items: center; font-size: .9rem; }
.order-lines img, .order-line-ph { width: 44px; height: 44px; border-radius: var(--r-sm); object-fit: cover; display: grid; place-items: center; background: var(--bg); color: var(--muted); }
.order-lines small { display: block; color: var(--muted); font-size: .8rem; }
.order-lines > li > span:last-child { font-weight: 700; font-variant-numeric: tabular-nums; }
@media (max-width: 760px) {
  .sh-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
  .sh-card-body { padding: 10px 10px 12px; }
  .sh-cardtile { grid-template-columns: auto minmax(0, 1fr); }
  .sh-cardtile > a { grid-column: 2; justify-self: start; }
  .sh-product .product-cta, .sh-product #sh-buy { display: none; }
  .sh-sticky { display: block; position: sticky; bottom: calc(var(--bottom-nav, 64px) + 8px); z-index: 50; margin-top: 12px; }
  .sh-sticky-in { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 10px 14px; border: 1px solid var(--border); border-radius: 16px; background: var(--card); box-shadow: var(--shadow-lg); }
  .sh-sticky-in > span { display: flex; flex-direction: column; min-width: 0; }
  .sh-sticky-in strong { font-size: 1.15rem; }
  .sh-sticky-in small { color: var(--muted); font-size: .8rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .sh-cart-grid { grid-template-columns: minmax(0, 1fr); }
  .sh-summary { position: static; }
  .sh-line { grid-template-columns: 60px minmax(0, 1fr) auto; }
  .sh-line-pic { width: 60px; height: 60px; }
  .sh-line-sum { grid-column: 2 / -1; text-align: right; }
}
/* the admin side of the shop (1.65.0): the product editor, the stock in the list */
.pe { display: grid; grid-template-columns: minmax(0, 1fr) 280px; gap: 16px; align-items: start; }
.pe-main { display: flex; flex-direction: column; gap: 14px; min-width: 0; }
.pe-main .form-card, .pe-side .form-card { margin: 0; }
.pe-side { position: sticky; top: 76px; display: flex; flex-direction: column; gap: 14px; }
.pe-sechead { display: flex; justify-content: space-between; align-items: center; gap: 8px; flex-wrap: wrap; }
.pe-sizes-add { display: flex; gap: 6px; }
.pe-pics { display: flex; flex-wrap: wrap; gap: 8px; }
.pe-pic { position: relative; width: 110px; height: 110px; border-radius: var(--r-sm); overflow: hidden; border: 1px solid var(--border); background: var(--bg); cursor: grab; }
.pe-pic.sm { width: 64px; height: 64px; }
.pe-pic img { width: 100%; height: 100%; object-fit: cover; display: block; }
.pe-pic.drag { opacity: .4; }
.pe-pic.over { outline: 2px solid var(--esn-cyan); }
.pe-pic-first { position: absolute; left: 0; right: 0; bottom: 0; padding: 2px 6px; background: rgba(18, 20, 42, .72); color: #fff; font-size: .75rem; font-weight: 700; text-align: center; }
.pe-pic-x { position: absolute; top: 4px; right: 4px; display: grid; place-items: center; width: 26px; height: 26px; border: 0; border-radius: 50%; background: rgba(255, 255, 255, .92); color: #12142a; cursor: pointer; }
.pe-color { padding: 10px; margin-bottom: 8px; border: 1px solid var(--border); border-radius: var(--r-md); background: var(--bg); }
.pe-color-row { display: grid; grid-template-columns: 40px minmax(120px, 2fr) minmax(0, 1fr) minmax(0, 1fr) auto auto; gap: 8px; align-items: center; }
.pe-color-row input:not([type="color"]), .pe-size input { min-height: 40px; padding: 8px 10px; border: 1px solid var(--border); border-radius: var(--r-sm); background: var(--card); color: var(--ink); font: inherit; min-width: 0; }
.pe-swatch { position: relative; display: block; width: 40px; height: 40px; border-radius: 50%; background: var(--sw, #c9ccd6); border: 1px solid rgba(0, 0, 0, .15); overflow: hidden; cursor: pointer; }
.pe-swatch input { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; cursor: pointer; }
.pe-color-pics { display: flex; align-items: flex-start; gap: 10px; flex-wrap: wrap; margin-top: 8px; }
.pe-sizes { display: flex; flex-direction: column; gap: 6px; }
.pe-size { display: grid; grid-template-columns: minmax(80px, 1fr) minmax(0, 1fr) minmax(0, 1fr) auto auto; gap: 8px; align-items: center; }
.pe-cells { display: flex; flex-wrap: wrap; gap: 8px; }
.pe-cell { display: flex; flex-direction: column; gap: 2px; min-width: 110px; }
.pe-cell span { font-size: .8rem; font-weight: 700; }
.pe-cell input { width: 100%; min-height: 40px; padding: 8px 10px; border: 1px solid var(--border); border-radius: var(--r-sm); background: var(--card); color: var(--ink); font: inherit; font-variant-numeric: tabular-nums; }
.pe-cell small { color: var(--muted); font-size: .75rem; }
.pe-grid th { font-size: .8rem; white-space: nowrap; }
.pe-grid td { padding: 4px; vertical-align: top; }
.pe-grid .pe-cell { min-width: 90px; }
.pe-grid .pe-cell span { display: none; }
.st-prod { display: flex; align-items: center; gap: 10px; }
.st-prod img, .st-prod > span { width: 44px; height: 44px; border-radius: var(--r-sm); object-fit: cover; display: grid; place-items: center; background: var(--bg); color: var(--muted); flex: none; }
.st-row { display: flex; align-items: center; flex-wrap: wrap; gap: 4px 10px; margin-top: 4px; font-size: .85rem; }
.st-cell { display: inline-flex; align-items: center; gap: 4px; white-space: nowrap; }
.st-cell small { color: var(--muted); }
.st-cell i { font-style: normal; }
@media (max-width: 899px) {
  .pe { grid-template-columns: minmax(0, 1fr); }
  .pe-side { position: static; }
  .pe-color-row { grid-template-columns: 40px minmax(0, 1fr) auto auto; }
  .pe-color-row input[data-f="price"], .pe-color-row input[data-f="priceEsn"] { grid-column: span 2; }
  .pe-size { grid-template-columns: minmax(0, 1fr) auto auto; }
  .pe-size input[data-f="price"], .pe-size input[data-f="priceEsn"] { grid-column: span 2; }
}

/* ---------- Light motion (1.69.5) ----------
   ux.js measures the frame times while a page arrives; on a phone that
   cannot keep up, html.lite-fx is set for the session and wantsMotion()
   says no (page slides, tilt, count-ups, confetti, smooth scrolls). Here:
   the entrances and the endless decorative loops stop. Functional motion
   (button spinners, the live dot, pull to refresh) stays. */
.lite-fx #app[data-enter] > *, .lite-fx #app[data-enter] .events-grid > *, .lite-fx #app[data-enter] :is(.tp-bar, .pp-badge-bar, .visa-bar, .scan-ev-bar, .join-progress, .pp-quest-bar) i { animation: none; }
.lite-fx .card-hero-card, .lite-fx .card-hero-tilt::before, .lite-fx .loading.sk::after, .lite-fx .dragon *, .lite-fx .pp-badge.earned::after, .lite-fx .pp-xp-bar::after, .lite-fx .pp-glow-5 .esncard, .lite-fx .pp-glow-6 .esncard, .lite-fx .globe-arc, .lite-fx .globe-beacon .beacon-pulse, .lite-fx .pt-pulse { animation: none; }
.lite-fx .card-pts-track.run { animation: none; }
.lite-fx .card-pts { overflow-x: auto; -webkit-mask-image: none; mask-image: none; }

/* ---------- Phones first (1.69.6) ---------- */
/* Typing: the bottom bar and the sticky price bars step aside (ux.js sets kb-open) */
@media (max-width: 820px) {
  .kb-open .bottom-nav, .kb-open .card-sticky { display: none; }
  .kb-open body { padding-bottom: env(safe-area-inset-bottom); }
  /* reading pages: the header slides away while scrolling down (ux.js sets hdr-hidden);
     the strip behind the status bar stays, so nothing scrolls under the clock */
  .site-header { transition: transform .25s ease; }
  .hdr-hidden .site-header { transform: translateY(calc(-100% + env(safe-area-inset-top))); }
}
/* An event's picture, whole */
.event-detail-banner[data-zoom] { position: relative; cursor: zoom-in; }
.ban-zoom { position: absolute; right: 10px; bottom: 10px; z-index: 2; width: 36px; height: 36px; border-radius: 50%; border: 0; display: flex; align-items: center; justify-content: center; background: rgba(18, 20, 56, .72); color: #fff; cursor: zoom-in; }
.pic-view { position: fixed; inset: 0; z-index: 230; display: flex; flex-direction: column; background: rgba(6, 7, 20, .95); animation: dlgFade .2s ease; }
.pic-view.closing { animation: dlgFadeOut .16s ease forwards; }
.pic-scroll { flex: 1; min-height: 0; overflow: auto; display: flex; align-items: center; justify-content: center; overscroll-behavior: contain; }
.pic-scroll img { max-width: 100%; max-height: 100%; object-fit: contain; cursor: zoom-in; touch-action: manipulation; }
.pic-view.zoomed .pic-scroll { display: block; }
.pic-view.zoomed .pic-scroll img { max-width: none; max-height: none; height: auto; cursor: zoom-out; }
.pic-close { position: absolute; top: calc(10px + env(safe-area-inset-top)); right: 12px; z-index: 2; width: 44px; height: 44px; border-radius: 50%; border: 0; display: flex; align-items: center; justify-content: center; background: rgba(255, 255, 255, .16); color: #fff; }
.pic-hint { position: absolute; left: 0; right: 0; bottom: calc(14px + env(safe-area-inset-bottom)); margin: 0; text-align: center; font-size: .8rem; color: #c9cbe6; pointer-events: none; }
/* After a ticket; out of the in-app browsers */
.after-buy, .ios-install { margin-bottom: 12px; }
.oib-title { display: flex; align-items: center; gap: 8px; margin: 0 0 8px; font-size: 1.05rem; }
.oib-steps { margin: 6px 0 14px; padding-left: 20px; line-height: 1.5; }
.oib-anyway { text-align: center; margin: 10px 0 0; }

/* ---------- What a visitor sees (1.70.0) ----------
   The home landing (guest.js guestHome) and the previews under every
   sign-in gate (guest.js fillGate): show what is behind the door. */
.g-hero { position: relative; overflow: hidden; margin: 14px 0 18px; padding: 18px 18px 16px; border-radius: var(--radius); color: #fff; background: radial-gradient(circle at 15% 0%, #3a3fb0 0%, #2E3192 40%, #1a1d5e 100%); box-shadow: var(--shadow-lg); animation: ppl-in .5s cubic-bezier(.2, .7, .3, 1) both; }
.g-hero-title { margin: 0 0 8px; font-size: 1.45rem; font-weight: 900; color: #fff; line-height: 1.2; }
.g-hero-lead { margin: 0 0 14px; font-size: 1rem; line-height: 1.5; color: #e4e6fb; max-width: 620px; }
.g-ctas { display: flex; flex-wrap: wrap; gap: 10px; margin: 0; }
.g-ctas .btn-google { min-height: 44px; }
.g-hero .g-cta-ghost { padding-left: 14px; padding-right: 14px; }  /* 1.78.9: fits beside Sign in on a 390 px phone */
/* 1.78.9: on a laptop the text sits beside the skyline (the children stay flat, so the early hero in index.html lays out the same) */
@media (min-width: 900px) {
  .g-hero { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.2fr); grid-template-areas: "title art" "lead art" "ctas art"; grid-template-rows: auto auto 1fr; column-gap: 28px; padding: 32px 0 0 32px; }
  .g-hero-art { grid-area: art; align-self: end; width: 100%; height: auto; aspect-ratio: 1200 / 460; margin: 0; }
  .g-hero-title { grid-area: title; align-self: end; font-size: 2rem; }
  .g-hero-lead { grid-area: lead; }
  .g-hero > .g-ctas { grid-area: ctas; align-self: start; margin-bottom: 32px; }
}
/* 1.74.0: the perks under the events: one column on a phone, a grid on a laptop, nothing clipped */
/* 1.76.2: the visitor's landing page: sections that reveal, a carousel of the next events, three numbers, a closing call */
.g-sec { margin: 26px 0 0; }
.g-sec-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.g-sec-head .section-title { margin-bottom: 0; }
.g-more-link { font-size: .85rem; font-weight: 700; white-space: nowrap; display: inline-flex; align-items: center; gap: 2px; }
.g-carousel-wrap { position: relative; margin-top: 12px; }
.g-carousel { display: flex; gap: 12px; overflow-x: auto; scroll-snap-type: x mandatory; scroll-padding: 0 16px; scrollbar-width: none; padding: 4px 16px 10px; margin: 0 -16px; -webkit-overflow-scrolling: touch; }
.g-carousel::-webkit-scrollbar { display: none; }
.g-carousel > div { flex: 0 0 min(78%, 280px); scroll-snap-align: start; }
.g-ev { display: flex; flex-direction: column; height: 100%; border-radius: var(--r-md); background: var(--card); border: 1px solid var(--border); overflow: hidden; color: var(--ink); box-shadow: var(--shadow); transition: transform .25s cubic-bezier(.2, .8, .2, 1), box-shadow .25s ease; }
.g-ev:hover { text-decoration: none; transform: translateY(-3px); box-shadow: var(--shadow-lg); }
.g-ev-pic { position: relative; display: block; aspect-ratio: 16 / 10; background: linear-gradient(135deg, var(--accent), color-mix(in srgb, var(--accent) 55%, #1a1d5e)); }
.g-ev-pic img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.g-ev-ic { position: absolute; top: 10px; left: 10px; width: 34px; height: 34px; border-radius: 10px; background: rgba(17, 19, 60, .72); color: #fff; display: inline-flex; align-items: center; justify-content: center; }
.g-ev-date { position: absolute; left: 10px; bottom: 10px; min-width: 46px; padding: 4px 8px; border-radius: 10px; background: #fff; color: var(--esn-dark); text-align: center; font-size: .75rem; font-weight: 800; text-transform: uppercase; letter-spacing: .04em; line-height: 1.1; }
.g-ev-date b { display: block; font-size: 1.15rem; letter-spacing: 0; }
.g-ev-soon { position: absolute; top: 10px; right: 10px; padding: 3px 9px; border-radius: 999px; background: var(--magenta-deep); color: #fff; font-size: .75rem; font-weight: 900; box-shadow: 0 2px 8px rgba(0, 0, 0, .25); }  /* 1.78.9: Today, Tomorrow */
.g-ev-main { display: flex; flex-direction: column; gap: 4px; padding: 10px 12px 12px; flex: 1; }
.g-ev-main > b { font-size: .95rem; line-height: 1.3; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.g-ev-main small { color: var(--muted); font-size: .8rem; line-height: 1.35; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.g-ev-foot { margin-top: auto; padding-top: 6px; display: flex; align-items: center; justify-content: space-between; gap: 8px; font-size: .8rem; }
.g-ev-foot em { font-style: normal; font-weight: 800; color: var(--accent-text); }
.g-ev-foot i { font-style: normal; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.g-car-btn { position: absolute; top: 40%; z-index: 2; width: 40px; height: 40px; border-radius: 50%; border: 1px solid var(--border); background: var(--card); color: var(--ink); box-shadow: var(--shadow-lg); display: inline-flex; align-items: center; justify-content: center; cursor: pointer; }
.g-car-btn.prev { left: -6px; } .g-car-btn.next { right: -6px; }
.g-car-btn:hover { background: var(--surface2); }
.g-who-lead { font-size: 1rem; line-height: 1.55; max-width: 680px; margin: 0 0 14px; }
.g-who-grid { display: grid; gap: 4px 28px; align-items: center; }  /* 1.78.9: the words and the numbers side by side on a laptop */
@media (min-width: 900px) { .g-who-grid { grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr); } .g-who-grid .g-who-lead { margin: 0; } }
.g-numgrid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
.g-num { background: var(--surface2); border-radius: var(--r-md); padding: 12px 12px 10px; }
.g-num-ic { display: inline-flex; align-items: center; justify-content: center; width: 30px; height: 30px; margin-bottom: 8px; border-radius: 9px; background: color-mix(in srgb, var(--esn-cyan) 16%, transparent); color: var(--accent-text); }
.g-num b { display: block; font-size: 1.7rem; font-weight: 900; line-height: 1; color: var(--accent-text); font-variant-numeric: tabular-nums; }
.g-num > span:last-child { display: block; margin-top: 6px; font-size: .8rem; color: var(--muted); }  /* 1.78.9: the label, not the icon's span */
/* the cards, the perks and the steps come in one after the other once their section is in view */
.an-section.an-armed .g-ev, .an-section.an-armed .g-perk, .an-section.an-armed .g-step, .an-section.an-armed .g-num { opacity: 0; transform: translateY(12px); transition: opacity .45s ease, transform .5s cubic-bezier(.2, .8, .2, 1); transition-delay: calc(var(--i, 0) * 70ms); }
.an-section.an-armed.in .g-ev, .an-section.an-armed.in .g-perk, .an-section.an-armed.in .g-step, .an-section.an-armed.in .g-num { opacity: 1; transform: none; }
.an-section.an-armed.in .g-ev:hover { transform: translateY(-3px); }
.g-ev-pic img { transition: transform .6s cubic-bezier(.2, .8, .2, 1); }
.g-ev:hover .g-ev-pic img { transform: scale(1.05); }
.g-steps { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 14rem), 1fr)); gap: 10px; }
.g-step { position: relative; background: var(--card); border: 1px solid var(--border); border-radius: var(--r-md); padding: 16px 14px 14px 14px; display: flex; flex-direction: column; gap: 4px; }
.g-step-n { position: absolute; top: 10px; right: 12px; font-size: 2rem; font-weight: 900; line-height: 1; color: color-mix(in srgb, var(--esn-cyan) 22%, transparent); }
.g-step-ic { width: 40px; height: 40px; border-radius: 12px; background: color-mix(in srgb, var(--esn-cyan) 14%, transparent); color: var(--esn-cyan); display: inline-flex; align-items: center; justify-content: center; margin-bottom: 6px; }
.g-step b { font-size: 1rem; color: var(--ink); }
.g-step small { font-size: .85rem; color: var(--muted); line-height: 1.4; }
@media (max-width: 600px) {  /* 1.78.9: rows, not tall cards */
  .g-step { display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: center; column-gap: 12px; row-gap: 2px; padding: 12px 40px 12px 12px; }
  .g-step-ic { grid-row: span 2; margin: 0; }
  .g-step-n { top: 50%; right: 12px; transform: translateY(-50%); font-size: 1.45rem; }
}
.g-numgrid .g-num { --i: 0; } .g-numgrid .g-num:nth-child(2) { --i: 1; } .g-numgrid .g-num:nth-child(3) { --i: 2; }
.g-newsgrid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 20rem), 1fr)); gap: 10px; }
.g-newsgrid .hnews { margin: 0; }
.g-final { margin: 30px 0 10px; padding: 24px 20px; border-radius: var(--radius); color: #fff; text-align: center; background: radial-gradient(circle at 80% 0%, #3a3fb0 0%, #2E3192 45%, #1a1d5e 100%); }
.g-final h2 { margin: 0 0 6px; font-size: 1.45rem; font-weight: 900; }
.g-final p { margin: 0 auto 16px; max-width: 520px; color: #e4e6fb; font-size: .95rem; line-height: 1.5; }
.g-final .g-ctas { justify-content: center; }
.g-cta-ghost { border-color: rgba(255, 255, 255, .35); color: #fff; min-height: 44px; }
.g-cta-ghost:hover { background: rgba(255, 255, 255, .12); color: #fff; }
.g-more { margin: 20px 0 6px; }
.g-perks { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr)); gap: 8px; margin: 0 0 16px; }
.g-perk { display: flex; align-items: center; gap: 12px; padding: 11px 12px; border-radius: var(--r-md); background: var(--card); border: 1px solid var(--border); color: var(--ink); min-width: 0; }
.g-perk:hover { text-decoration: none; background: var(--surface2); }
.g-perk-main { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; }
.g-perk b { font-size: .95rem; color: var(--accent-text); }
.g-perk small { font-size: .8rem; color: var(--muted); line-height: 1.4; }
.g-perk .chev { color: var(--muted); }
.g-perk-ic { width: 36px; height: 36px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; background: color-mix(in srgb, var(--esn-cyan) 14%, transparent); color: var(--esn-cyan); flex: none; }
.g-more .join-pics { margin: 0; }
.g-more .crew-kicker { margin-bottom: 6px; }
.ea-local { margin: 8px 0 0; border-left: 4px solid var(--esn-cyan); }  /* 1.74.0: a local student on the apply form */
/* the gates */
.guest-more { max-width: 460px; margin: 18px auto 0; text-align: left; }
.guest-more:empty { display: none; }
.g-cap { font-size: .85rem; color: var(--muted); text-align: center; margin: 10px 0 14px; line-height: 1.45; }
.g-ticket { border-radius: var(--radius); overflow: hidden; background: var(--card); border: 1px solid var(--border); box-shadow: var(--shadow-lg); animation: ppl-in .5s cubic-bezier(.2, .7, .3, 1) both; }
.g-ticket-top { display: flex; flex-direction: column; gap: 2px; padding: 14px 16px; color: #fff; background: linear-gradient(135deg, var(--accent, #EC008C), color-mix(in srgb, var(--accent, #EC008C) 55%, #1a1d5e)); }
.g-ticket-top small { font-size: .75rem; text-transform: uppercase; letter-spacing: .08em; opacity: .85; }
.g-ticket-top b { font-size: 1.05rem; }
.g-ticket-top span { font-size: .85rem; opacity: .9; }
.g-ticket-body { display: flex; align-items: center; gap: 14px; padding: 14px 16px; border-top: 2px dashed var(--border); }
.g-ticket-body p { margin: 0; font-size: .85rem; color: var(--muted); line-height: 1.45; }
.g-qr { flex: none; width: 76px; height: 76px; border-radius: 8px; background:
  conic-gradient(from 90deg at 2px 2px, var(--ink) 25%, transparent 0) 0 0 / 12px 12px,
  repeating-linear-gradient(45deg, var(--ink) 0 3px, transparent 3px 7px);
  opacity: .5; filter: blur(.6px); border: 6px solid var(--card); outline: 1px solid var(--border); }
.g-cardprev { perspective: 1200px; }
.g-cardprev .esncard { max-width: 400px; margin: 0 auto; }
.g-globe { text-align: center; padding: 14px; border-radius: var(--radius); background: var(--card); border: 1px solid var(--border); }
.g-globe-n { margin: 0 0 10px; font-size: .95rem; }
.g-globe-n b { font-size: 1.45rem; color: var(--cyan-text); margin-right: 4px; }  /* 1.78.4: 4.7:1 on white */
.g-flags { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; }
.g-flag { display: inline-flex; flex-direction: column; align-items: center; gap: 2px; font-size: 1.45rem; animation: pp-tile-in .4s cubic-bezier(.22, 1, .36, 1) both; }
.g-flag small { font-size: .75rem; color: var(--muted); max-width: 64px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.g-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.g-list li { display: flex; gap: 12px; align-items: flex-start; padding: 12px; border-radius: var(--r-md); background: var(--card); border: 1px solid var(--border); }
.g-list .g-perk-ic { background: color-mix(in srgb, var(--esn-cyan) 14%, transparent); color: var(--esn-cyan); margin: 0; }
.g-list b { display: block; font-size: .95rem; }
.g-list small { display: block; color: var(--muted); font-size: .85rem; line-height: 1.4; }
.g-alt { padding: 14px 16px; border-radius: var(--r-md); background: var(--card); border: 1px solid var(--border); }
.g-alt p { margin: 0 0 6px; }
.g-alt .material-symbols-rounded { vertical-align: -3px; margin-right: 4px; color: var(--muted); }
.g-alt p:last-child { margin: 0; }
.g-peek { padding: 14px 16px; border-radius: var(--r-md); background: var(--card); border: 1px solid var(--border); }
.g-peek ul { margin: 6px 0 0; padding-left: 18px; line-height: 1.7; }
.g-peek .g-blur { filter: blur(3.5px); user-select: none; }
.g-newsend { margin: 18px 0 0; padding: 16px; border-radius: var(--radius); background: var(--card); border: 1px solid var(--border); border-left: 4px solid var(--esn-cyan); }
.g-newsend p { margin: 0 0 10px; }
.guest-more .guest-card { margin-top: 0; }


/* ---------- The Team hub, the home scope toggle, polls (1.78.0) ---------- */
.home-scope { display: flex; gap: 8px; margin: -6px 0 14px; flex-wrap: wrap; }
.home-scope .chip { display: inline-flex; align-items: center; gap: 6px; }
.home-scope .chip b { font-variant-numeric: tabular-nums; padding: 0 7px; border-radius: 999px; background: var(--surface2); color: var(--ink); font-size: .75rem; line-height: 1.6; }
.home-scope .chip.active b { background: rgba(255, 255, 255, .22); color: #fff; }
.ev-tag.is-team { display: inline-flex; align-items: center; gap: 3px; background: var(--esn-dark); color: #fff; }
.ev-tag.is-team::before { content: none; }
.ev-tag.is-team .material-symbols-rounded { font-size: 14px; }
html[data-theme="dark"] .ev-tag.is-team { background: var(--esn-cyan); color: var(--on-bright); }
.poll-card { margin: 0 0 18px; border-left: 4px solid var(--esn-cyan); }
.poll-q { margin: 2px 0 10px; font-size: 1.05rem; line-height: 1.3; }
.poll-opts { display: flex; flex-wrap: wrap; gap: 8px; }
.poll-text { width: 100%; resize: vertical; }
.poll-results { list-style: none; margin: 0 0 6px; padding: 0; display: grid; gap: 6px; }
.poll-results li { display: grid; grid-template-columns: minmax(80px, 1fr) 2fr 40px; align-items: center; gap: 8px; font-size: .85rem; }
.poll-opt-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.poll-bar { display: block; height: 10px; border-radius: 5px; background: var(--surface2); overflow: hidden; }
.poll-bar i { display: block; height: 100%; background: var(--esn-cyan); border-radius: 5px; transition: width .4s ease; }
.poll-n { text-align: right; font-variant-numeric: tabular-nums; color: var(--muted); }
.poll-answer-rows { list-style: none; margin: 10px 0 0; padding: 0; display: grid; gap: 8px; }
.poll-answer-rows li { padding: 8px 0 0; border-top: 1px solid var(--border); font-size: .9rem; }
.al-years { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }  /* 1.78.13: a year beside the taller "Before" chip keeps its own height */
.al-years .chip-check { font-size: .8rem; }
details.al-older { margin-top: 8px; }  /* 1.78.10: the board years before the last twelve (1.78.13: the fold-out only; on the answer page the "Before" chip sits in the row) */
.al-compose { display: grid; gap: 10px; margin: 0 0 12px; }  /* 1.78.10: the invitation, written and tested before it goes */
.al-preview iframe { display: block; width: 100%; height: 560px; border: 1px solid var(--border); border-radius: var(--r-md); background: #f2f3f8; }
/* 1.78.11: the alumni newsletter (alumni-page.js renderNews): blocks in fieldsets, each with up, down and remove */
.nl-edit { display: grid; gap: 12px; }
.nl-edit .dash-title { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px; }
.nl-blocks { display: grid; gap: 10px; }
.nl-block { position: relative; margin: 0; padding: 10px 12px 4px; border: 1px solid var(--border); border-left: 4px solid var(--esn-cyan); border-radius: var(--r-md); background: var(--card); min-width: 0; }
.nl-block > legend { display: inline-flex; align-items: center; gap: 4px; padding: 0 6px; font-size: .8rem; font-weight: 700; color: var(--ink); }
.nl-block-acts { display: flex; justify-content: flex-end; gap: 4px; margin: -4px 0 4px; }
.nl-add { display: flex; flex-wrap: wrap; gap: 6px; }
.nl-to { margin: 0; padding: 10px 12px; border: 1px solid var(--border); border-radius: var(--r-md); display: grid; gap: 6px; min-width: 0; }
.nl-to > legend { padding: 0 6px; font-size: .8rem; font-weight: 700; }
.unsub-card { max-width: 520px; margin: 24px auto; text-align: center; }  /* 1.78.10: /rsvp/unsubscribe */
.unsub-card .form-actions { justify-content: center; }
.al-older > summary { cursor: pointer; font-size: .85rem; font-weight: 700; color: var(--accent-text); margin-bottom: 6px; }
.al-edit-form { padding: 4px 0; }
.rsvp-page { max-width: var(--w-read); margin: 0 auto; padding-top: 16px; }  /* 1.78.13: room under the top bar, as on the other pages */
.rsvp-form, .rsvp-gate, .rsvp-thanks { display: flex; flex-direction: column; gap: 16px; }  /* 1.78.13: one even step between the parts of the answer form, the sign-in card and the thanks */
.rsvp-form > *, .rsvp-gate > *, .rsvp-thanks > * { margin-top: 0; margin-bottom: 0; }
.rsvp-card { margin: 0 0 14px; }
.rsvp-img { width: 100%; height: auto; border-radius: var(--r-sm); margin: 10px 0 4px; }
.rsvp-desc { margin: 10px 0 0; font-size: .95rem; }
.rsvp-status .chip { display: inline-flex; align-items: center; gap: 6px; min-height: 44px; }
/* 1.78.13: GREEN yes, ORANGE maybe, RED no: the icon in its colour, the chosen one filled; Send follows the choice */
.rsvp-status .chip[data-st="yes"] .material-symbols-rounded { color: var(--green-text); }
.rsvp-status .chip[data-st="maybe"] .material-symbols-rounded { color: var(--orange-text); }
.rsvp-status .chip[data-st="no"] .material-symbols-rounded { color: var(--danger); }
.rsvp-status .chip[data-st="yes"].active { background: var(--esn-green); border-color: var(--esn-green); color: var(--on-bright); }
.rsvp-status .chip[data-st="maybe"].active { background: var(--esn-orange); border-color: var(--esn-orange); color: var(--on-bright); }
.rsvp-status .chip[data-st="no"].active { background: var(--danger); border-color: var(--danger); color: #fff; }
html[data-theme="dark"] .rsvp-status .chip[data-st="no"].active { color: var(--on-bright); }  /* the lighter red of the dark theme carries dark ink */
.rsvp-status .chip.active .material-symbols-rounded { color: inherit; }
.rs-send[data-st="yes"] { background: var(--esn-green); color: var(--on-bright); }
.rs-send[data-st="maybe"] { background: var(--esn-orange); color: var(--on-bright); }
.rs-send[data-st="no"] { background: var(--danger); color: #fff; }
html[data-theme="dark"] .rs-send[data-st="no"] { color: var(--on-bright); }
.rsvp-me { display: flex; align-items: center; gap: 10px; padding: 10px 12px; border: 1px solid var(--border); border-radius: var(--r-md); background: var(--surface2); }
.rsvp-me p { flex: 1; min-width: 0; overflow-wrap: anywhere; }
.rsvp-me-ico { display: inline-flex; color: var(--accent-text); }
.rsvp-ways { display: flex; flex-direction: column; gap: 10px; }
.rsvp-google { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; }
.rsvp-or { display: flex; align-items: center; gap: 10px; margin: 0; color: var(--muted); font-size: .85rem; }
.rsvp-or::before, .rsvp-or::after { content: ""; flex: 1; height: 1px; background: var(--border); }
.rsvp-share { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 10px; padding: 12px 14px; border-radius: var(--r-md); background: var(--surface2); }
.ledger-line .money-lbl { padding-left: 14px; }
.ledger-form { margin-top: 10px; }
.crew-team-events { margin: 0 0 18px; }
#hide-mail-row { cursor: pointer; }
.cash-register .cash-now { margin: 4px 0 10px; font-size: 1.15rem; }
.cash-register .cash-now strong { font-size: 1.7rem; }
.cash-history .cash-line-row { display: grid; grid-template-columns: 96px 1fr auto; gap: 10px; align-items: baseline; }
.cash-history .cash-line-main { min-width: 0; }
@media (max-width: 700px) { .cash-history .cash-line-row { grid-template-columns: 1fr auto; } .cash-history .cash-line-row .info-label { grid-column: 1 / -1; } }
.rw-card, .rw-page { text-align: left; }
.rw-qr { display: flex; justify-content: center; padding: 14px; background: #fff; border-radius: var(--r-sm); margin: 10px 0; }
.rw-qr img, .rw-qr canvas { display: block; }
.rw-code { margin: 10px 0 4px; }
.rw-code code { font-size: 1.45rem; letter-spacing: 2px; padding: 6px 12px; background: var(--surface2); border-radius: var(--r-sm); }
.crew-rewards { margin: 0 0 18px; }
#rw-tiers .inline-input { min-width: 0; }

/* ---------- Admin, Settings, Locations (1.78.0): the map and the most-used strip ---------- */
.vn-top { display: grid; grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr); gap: 14px; margin: 0 0 18px; }
.vn-map { min-height: 260px; }
.vn-most-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; }
.vn-most-list li { display: grid; grid-template-columns: minmax(0, 1fr) 90px 2ch; align-items: center; gap: 8px; font-size: .85rem; }
.vn-most-list .linkish { text-align: left; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.vn-bar { display: block; height: 8px; border-radius: 4px; background: var(--surface2); overflow: hidden; }
.vn-bar i { display: block; height: 100%; width: var(--p, 0%); background: var(--esn-cyan); border-radius: 4px; }
.vn-most-list b { text-align: right; font-size: .85rem; }
@media (max-width: 820px) {
  .vn-top { grid-template-columns: minmax(0, 1fr); }
}
.settings-ro-note { display: flex; gap: 8px; align-items: flex-start; margin: 0 0 12px; padding: 10px 12px; border-radius: var(--r-md); background: var(--surface2); border: 1px solid var(--border); color: var(--muted); font-size: .85rem; line-height: 1.45; }

.prefs-card .prefs-menu { border: 1px solid var(--border); border-radius: var(--r-md); overflow: hidden; margin: 8px 0 10px; }
.prefs-card .prefs-menu > :last-child { border-bottom: none; }

/* ---------- Team events stand out (1.78.0): a band on the picture, a tinted card; the Team page's event cards ---------- */
.team-band { position: absolute; right: 10px; bottom: 10px; z-index: 2; background: var(--esn-cyan); color: var(--on-bright); font-weight: 900; font-size: .75rem; letter-spacing: .8px; text-transform: uppercase; padding: 5px 10px; border-radius: 999px; box-shadow: var(--shadow); display: inline-flex; align-items: center; gap: 4px; }
.team-band .material-symbols-rounded { font-size: 14px; }
.event-card.is-team { border-top-color: var(--esn-cyan); box-shadow: 0 0 0 2px var(--esn-cyan), var(--shadow); }
.event-card.is-team .card-body { background: color-mix(in srgb, var(--esn-cyan) 9%, var(--card)); }
.team-ev-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 14px; margin: 0 0 18px; }
.team-ev { display: flex; flex-direction: column; background: var(--card); border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; box-shadow: 0 0 0 2px var(--esn-cyan), var(--shadow); color: var(--ink); text-decoration: none; position: relative; }
.team-ev:hover { text-decoration: none; box-shadow: 0 0 0 2px var(--esn-cyan), var(--shadow-lg); }
.team-ev .card-media { aspect-ratio: 2 / 1; }
.team-ev .card-media > .ev-ico { position: absolute; top: 10px; right: 10px; }
.team-ev-body { padding: 10px 14px 12px; display: flex; flex-direction: column; gap: 4px; background: color-mix(in srgb, var(--esn-cyan) 9%, var(--card)); flex: 1; }
.team-ev-body strong { font-size: .95rem; line-height: 1.3; }
.team-ev-body small { color: var(--muted); font-size: .8rem; line-height: 1.5; }
.team-ev-who { font-size: .75rem; font-weight: 700; color: var(--accent-text); margin-top: auto; }

/* ---------- Team hub dashboard row (1.78.1) and the knowledge-transfer book on the organigram ---------- */
.team-dash { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 10px; margin: 0 0 18px; }
.team-dash-tile { display: flex; flex-direction: column; gap: 2px; padding: 12px 14px; background: var(--card); border: 1px solid var(--border); border-radius: var(--r-md); color: var(--ink); text-decoration: none; box-shadow: var(--shadow); min-height: 84px; }
.team-dash-tile:hover { text-decoration: none; background: var(--hover); }
.team-dash-tile .tdt-n { font-size: 1.45rem; font-weight: 900; line-height: 1.1; color: var(--accent-text); }
.team-dash-tile .tdt-n .material-symbols-rounded { font-size: 28px; }
.team-dash-tile .tdt-l { font-size: .85rem; font-weight: 700; }
.team-dash-tile small { color: var(--muted); font-size: .75rem; }
.team-dash-tile.is-late { border-color: var(--esn-orange); }
.team-dash-tile.is-late .tdt-n { color: var(--orange-text); }
.orgp-doc { display: inline-flex; align-items: center; justify-content: center; width: 28px; height: 28px; border-radius: 50%; margin-left: -6px; color: var(--accent-text); background: var(--surface2); vertical-align: middle; }
.orgp-doc:hover { background: var(--hover); text-decoration: none; }
/* 1.78.1: a donut inside a card wears the card */
.form-card > .donut { border: 0; padding: 8px 0 0; background: transparent; }

/* ---------- Animations (1.78.1): the stamp moment's actions, the fresh ticket, the QR reveal ---------- */
.sm-actions.sm-rise { animation: sm-rise .5s ease 1.3s both; }
.stamp-moment .sm-sub, .stamp-moment .sm-level { animation: sm-rise .5s ease .9s both; }
.tkt.tkt-new { animation: tkt-in .7s cubic-bezier(.2, 1.1, .3, 1) both; transform-origin: 50% 20%; }
@keyframes tkt-in { 0% { opacity: 0; transform: translateY(40px) rotateX(18deg) scale(.96); } 100% { opacity: 1; transform: none; } }
#qr { opacity: 0; transition: opacity .45s ease, transform .45s ease; transform: scale(.94); }
#qr.qr-ready, #qr:has(p) { opacity: 1; transform: none; }
