:root {
  --bg: #140E0A; --card: #2A1B10; --line: #4A3622; --line-soft: #3B2A14;
  --gold: #C9A45C; --gold-bright: #E2C384; --champagne: #EBD9B0; --ivory: #F5EEDF; --sand: #D9CDB6;
  --muted: #9C8A70; --dim: #95836A; --edge: #7A6A52; --cream: #F3EDE2; --paper: #FFFDF8; --ink: #2A1B10;
  --warn: #D98A6C; /* terracotta: the bad habits and Don't invite (loop cycle 11) */
  --display: 'Cinzel', Georgia, serif; --body: 'Jost', system-ui, sans-serif;
}
* { box-sizing: border-box; }
html, body { margin: 0; }
body { background: var(--bg); color: var(--ivory); font-family: var(--body); font-weight: 300; -webkit-font-smoothing: antialiased; }
a { color: var(--gold); text-decoration: none; }
a:hover { color: var(--gold-bright); }
/* select too (run 2, P139): the club picker on NFC cards was in the system font. Textareas set `font: inherit`. */
button, input, select { font-family: var(--body); font-size: inherit; }
:focus-visible { outline: 2px solid var(--gold); outline-offset: 3px; }
.display, h1, h2, h3 { font-family: var(--display); font-weight: 600; margin: 0; }
.muted { color: var(--muted); }
.gold { color: var(--gold); }
.small { font-size: 12.5px; }
.tracked { letter-spacing: 0.22em; font-size: 12px; }
.center { text-align: center; }

/* phone column */
body.phone main { max-width: 390px; min-height: 100dvh; margin: 0 auto; padding: 64px 28px 40px; display: flex; flex-direction: column; gap: 26px; background: radial-gradient(ellipse 90% 45% at 50% -8%, #3B2A14 0%, var(--bg) 60%); }
body.phone main.between { justify-content: space-between; }
.wordmark { font-family: var(--display); font-size: 13px; letter-spacing: 0.34em; color: var(--gold); font-weight: 600; text-align: center; }
.rule { width: 36px; height: 1px; background: var(--gold); margin: 8px auto 0; }
.stack { display: flex; flex-direction: column; gap: 12px; }
.row { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
h1 { font-size: 26px; line-height: 1.15; }
p { margin: 0; font-size: 15px; line-height: 1.55; color: var(--sand); }
.btn { display: flex; align-items: center; justify-content: center; gap: 12px; height: 58px; border-radius: 14px; background: var(--gold); color: var(--bg); font-size: 17px; font-weight: 500; border: 0; width: 100%; cursor: pointer; }
.btn:hover { background: var(--gold-bright); color: var(--bg); }
.btn-ghost { display: flex; align-items: center; justify-content: center; height: 52px; border-radius: 14px; border: 1px solid #5A4630; color: var(--sand); font-size: 16px; background: transparent; width: 100%; cursor: pointer; }
.btn-quiet { display: flex; align-items: center; justify-content: center; height: 48px; color: var(--muted); font-size: 15px; background: transparent; border: 0; width: 100%; cursor: pointer; }
/* Retire and Re-issue close a door: the warning colour, apart from each other (run 2, P134). */
.btn-small.danger { border-color: var(--warn); color: var(--warn); }
.card-acts { display: flex; flex-wrap: wrap; gap: 16px; }
/* Wide enough for its example, on its own line on a phone: the select in the app font pushed it to "Front doo". */
#new input[name="label"] { flex: 1 1 300px; max-width: 420px; min-width: 0; }
/* A card's one-time URL is one 50-character word: it ran 12 px off a phone in the notice and in its row (cycle I). */
.notice code, table.night td code { overflow-wrap: anywhere; min-width: 0; }
.once-url { margin: 8px 0 10px; }
.notice .card-acts + .small { margin-top: 8px; }
.btn-small { height: 38px; padding: 0 16px; border-radius: 10px; border: 1px solid var(--gold); background: transparent; color: var(--gold); font-size: 14px; cursor: pointer; display: inline-flex; align-items: center; white-space: nowrap; }
.card { padding: 28px 24px; border-radius: 20px; background: var(--card); border: 1px solid var(--line); }
.avatar { width: 88px; height: 88px; border-radius: 50%; background: #3B2A14; border: 2px solid var(--gold); display: flex; align-items: center; justify-content: center; font-family: var(--display); font-size: 28px; color: var(--gold); object-fit: cover; margin: 0 auto; }
.field { display: flex; flex-direction: column; gap: 8px; }
.field span { font-size: 14px; color: var(--gold); }
.field input { width: 100%; height: 54px; padding: 0 16px; border-radius: 14px; border: 1px solid var(--edge); background: var(--card); color: var(--ivory); font-size: 17px; outline: none; }
.field input::placeholder { color: var(--dim); }
/* The night list pastes handles and edits the invite: a textarea styled like the inputs, not the browser's white box. */
textarea { width: 100%; padding: 12px 16px; border-radius: 14px; border: 1px solid var(--edge); background: var(--card); color: var(--ivory); font: inherit; font-size: 15px; line-height: 1.5; outline: none; resize: vertical; }
textarea::placeholder { color: var(--dim); }
/* Design audit (2026-09-29): outline: none above outranks the gold :focus-visible ring, so a selected field looked
   like every other one. A field's edge is what shows it: it turns gold (and 3:1 at rest, --edge, WCAG 1.4.11). */
.field input:focus, textarea:focus { border-color: var(--gold); box-shadow: 0 0 0 1px var(--gold); }
/* Create an event (drawing 3): labels in the quiet colour, the club picker drawn like the boxes, the photo box dashed. */
.create-form { gap: 18px; max-width: 480px; }
.create-form .field-label { color: var(--muted); }
.field-group { display: flex; flex-direction: column; gap: 8px; }
.field-hint { margin: 0; font-size: 13.5px; color: var(--muted); }
.select-wrap { position: relative; display: block; }
.select-wrap select { width: 100%; height: 54px; padding: 0 44px 0 16px; border-radius: 14px; border: 1px solid var(--edge); background: var(--card); color: var(--ivory); font-family: inherit; font-size: 17px; -webkit-appearance: none; appearance: none; }
.select-wrap::after { content: ''; position: absolute; right: 20px; top: 50%; width: 8px; height: 8px; margin-top: -6px; border-right: 1.5px solid var(--sand); border-bottom: 1.5px solid var(--sand); transform: rotate(45deg); pointer-events: none; }
.select-wrap select:focus { border-color: var(--gold); box-shadow: 0 0 0 1px var(--gold); outline: none; }
.field input[type="date"] { -webkit-appearance: none; appearance: none; text-align: left; }
.photo-drop { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 12px; min-height: 96px; padding: 16px; border: 1px dashed var(--edge); border-radius: 14px; text-align: center; cursor: pointer; }
.photo-drop:focus-within { border-color: var(--gold); outline: 2px solid var(--gold); outline-offset: 2px; }
.field .photo-drop .photo-note { color: var(--muted); font-size: 14.5px; }
/* Shown with the invitation's own crop (.cover.has-photo: full width, 240 px tall on a phone), so the team sees what
   the models will see, not the whole photo. */
.photo-drop img, .photo-drop canvas { display: block; width: 100%; height: auto; aspect-ratio: 334 / 240; object-fit: cover; border-radius: 10px; }
.photo-drop [hidden], .photo-clear[hidden] { display: none !important; }
.photo-clear { align-self: flex-start; }
/* The "Who we follow" picker: the whole handle is the checkbox's label, so a tap anywhere on it ticks it. */
label.pick { display: inline-flex; align-items: center; gap: 10px; cursor: pointer; }
label.pick input { width: 18px; height: 18px; accent-color: var(--gold); }
.handle { display: flex; align-items: center; justify-content: space-between; height: 54px; padding: 0 8px 0 16px; border-radius: 14px; background: var(--card); border: 1px solid var(--line); font-size: 17px; font-weight: 500; }
.dashed { padding: 14px 16px; border-radius: 14px; border: 1px dashed var(--line); }
.seal { width: 216px; height: 216px; margin: 0 auto; border-radius: 50%; border: 2px solid var(--gold); padding: 9px; display: flex; animation: seal-in 600ms ease-out 1; }
.seal > div { flex-grow: 1; border-radius: 50%; border: 1px solid var(--gold); display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px; text-align: center; }
.seal .eyebrow { font-size: 11px; letter-spacing: 0.3em; color: var(--gold); }
.seal .date { font-family: var(--display); font-size: 28px; font-weight: 600; line-height: 1.1; }
.seal .venue { font-family: var(--display); font-size: 14px; letter-spacing: 0.06em; color: var(--champagne); }
@keyframes seal-in { from { opacity: 0; transform: scale(0.94); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .seal { animation: none; } }
.stats { display: flex; flex-wrap: wrap; row-gap: 14px; padding: 18px 8px; border-radius: 20px; background: var(--card); border: 1px solid var(--line); text-align: center; }
/* flex-wrap (design audit, 2026-09-29): the club page's seven numbers pushed the page 25 px past a 390 px phone.
   A row that fits stays one row; one that does not goes onto a second line instead of sideways. */
.stats > div { flex: 1 1 0; }
.stats > div:not(.sep) { padding: 0 8px; }
@media (max-width: 600px) { .stats .sep { display: none; } }
.stats .n { font-family: var(--display); font-size: 22px; }
.stats .sep { flex: 0 0 1px; background: var(--line); }
.notice { padding: 14px 16px; border-radius: 14px; background: var(--card); border: 1px solid var(--line); color: var(--sand); font-size: 15px; line-height: 1.5; }
/* System health: a server variable, folded under the plain words (run 2, P154). */
details.dev { margin-top: 6px; font-size: 13.5px; color: var(--muted); overflow-wrap: anywhere; }
details.dev summary { display: list-item; padding: 12px 0; cursor: pointer; color: var(--sand); }
/* The team's Don't invite mark (loop cycle 11): the word, the reason, who and when — each on its own line. */
.dont-invite { display: grid; gap: 4px; justify-items: start; padding: 14px 16px; border-radius: 14px; border: 1px solid var(--warn); color: var(--ivory); font-size: 15px; line-height: 1.5; }
.dont-invite b { color: var(--warn); font-weight: 500; }
.dont-invite form { margin-top: 8px; }

/* admin */
body.wide { min-height: 100vh; }
.admin { display: flex; min-height: 100vh; }
.rail { width: 236px; flex: 0 0 236px; padding: 36px 24px; border-right: 1px solid var(--card); display: flex; flex-direction: column; gap: 28px; }
.rail .wordmark { text-align: left; font-size: 14px; letter-spacing: 0.3em; }
.rail .group { display: flex; flex-direction: column; gap: 6px; }
.rail .group .label { font-size: 12.5px; color: var(--dim); padding: 0 12px 6px; }
.rail a { display: flex; align-items: center; justify-content: space-between; padding: 11px 12px; border-radius: 10px; color: var(--sand); font-size: 15px; }
.rail a.on { background: var(--card); color: var(--ivory); }
.main { flex-grow: 1; min-width: 0; padding: 36px 40px; display: flex; flex-direction: column; gap: 26px; }
.main h1 { font-size: 28px; }
.lead { font-size: 16px; color: var(--sand); }
.toolbar { display: flex; gap: 10px; flex-wrap: wrap; }
.btn-line { height: 42px; padding: 0 18px; border-radius: 10px; border: 1px solid var(--edge); background: transparent; color: var(--sand); font-size: 14.5px; cursor: pointer; display: inline-flex; align-items: center; }
/* min-height, not height (2026-09-25): at phone width "Copy contacts of guests who have not posted (N)" wraps
   to three lines and a fixed 42px cut the first and last off. One line still renders 42px (border-box). */
.btn-fill { min-height: 42px; padding: 10px 18px; line-height: 1.3; border-radius: 10px; border: 1px solid var(--gold); background: var(--gold); color: var(--bg); font-size: 14.5px; font-weight: 500; cursor: pointer; display: inline-flex; align-items: center; }
/* A disabled gold button looked exactly like one that works (cycle G verifier, P162): outlined and dim instead. */
.btn-fill:disabled { background: transparent; border-color: var(--edge); color: var(--dim); cursor: not-allowed; }
.btn-line:disabled { border-style: dashed; color: var(--dim); cursor: not-allowed; }
/* System health: a block's state stays one phrase on the phone ("1 to fix", "Not checked"). */
.card h3 > .warn-t, .card h3 > .yes, .card h3 > .muted { white-space: nowrap; }
.chips { display: flex; gap: 8px; flex-wrap: wrap; }
.chip { height: 34px; padding: 0 14px; border-radius: 999px; border: 1px solid var(--line-soft); background: transparent; color: var(--muted); font-size: 13.5px; display: inline-flex; align-items: center; }
.chip.on { border-color: var(--gold); background: var(--card); color: var(--champagne); }
.panel { border-radius: 16px; border: 1px solid var(--card); background: #1A120C; padding: 18px 6px 6px; overflow-x: auto; }
/* The Instagram connection page (run 2, cycle L): the facts, Connect, the steps and Advanced, one under another.
   `.panel.connect-panel`, so the phone's `.panel { padding: 4px 6px }` below does not squeeze it (the old page had an inline style). */
.panel.connect-panel { padding: 20px; display: flex; flex-direction: column; gap: 16px; max-width: 720px; }
.connect-panel h3 { margin: 0; }
/* The panel's 16 px gap is the only space between the facts and Connect, and Connect has 8 px more below it: the
   button belongs to the facts it answers, not to the steps (verifier L5: it was 36 px above and 16 px below). */
.connect-panel dl.facts { margin: 0; }
.panel.connect-panel > .toolbar { margin-bottom: 8px; }
.connect-panel .advanced p { margin: 0 0 10px; }
table.night { border-collapse: collapse; width: 100%; }
table.night th { text-align: left; font-weight: 400; font-size: 13px; color: var(--muted); padding: 0 14px 12px; border-bottom: 1px solid var(--line-soft); }
table.night td { padding: 15px 14px; font-size: 15px; border-bottom: 1px solid #241810; vertical-align: middle; }
.yes { color: var(--champagne); }
.no { color: var(--dim); }
.score { font-family: var(--display); color: var(--gold); }
.foot { padding: 14px 14px 8px; font-size: 13px; color: var(--dim); }
form.inline { display: inline; }
.grid2 { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; }
/* The folded phone menu (loop cycle 6). On a computer its parts lay out exactly as before. */
.menu-toggle { position: absolute; width: 1px; height: 1px; opacity: 0; }
/* On a computer the rail is always shown and the box does nothing: out of the Tab order, so Space on it cannot tick a
   menu nobody sees (verifier V-2, M1). */
/* The exact opposite of the phone rule (review run 3, R5): min-width 901px left 900-901 px to neither. */
@media not all and (max-width: 900px) { .menu-toggle { display: none; } }
.menu-open { display: none; }
.menu-body { display: contents; }
/* On a phone the rail was stacking its fourteen links vertically above the page, so the host had to
   scroll past roughly 800px of menu to reach the night — the one screen used at the door. It becomes a
   compact strip of scrolling chips instead. Since loop cycle 6 (2026-10-03) the strip itself folds behind one
   button on a phone: it still took 320 px, with links off-screen ("phone basics", end of this file). */
@media (max-width: 900px) {
  .admin { flex-direction: column; }
  .rail { width: auto; flex: none; border-right: 0; border-bottom: 1px solid var(--card);
          flex-direction: row; flex-wrap: wrap; align-items: center; gap: 8px; padding: 12px 16px; }
  .rail .wordmark { flex: 1 0 100%; font-size: 12px; }
  .rail .group { flex-direction: row; flex-wrap: nowrap; gap: 8px; overflow-x: auto; max-width: 100%;
                 scrollbar-width: none; }
  .rail .group::-webkit-scrollbar { display: none; }
  .rail .group .label { display: none; }
  .rail a { padding: 8px 12px; font-size: 14px; gap: 8px; white-space: nowrap;
            border: 1px solid var(--card); border-radius: 999px; }
  .rail form { margin-left: auto; }
  .main { padding: 24px 16px; }
}
.demo-bar { background: #5A4630; color: #F5EEDF; text-align: center; font-size: 13px; padding: 8px 12px; letter-spacing: 0.02em; }

/* Counts in tables line up under their heading (the per-club columns on Models). */
table.night td.num, table.night th.num { text-align: center; }

/* The club's own link (/club/<token>): a wide page with no rail, so it carries its own margins. It had none, and
   on a phone its text touched both edges of the screen (2026-10-09). */
main.club-link { max-width: 960px; margin: 0 auto; padding: 32px 40px 48px; display: flex; flex-direction: column; gap: 18px; }
@media (max-width: 900px) { main.club-link { padding: 24px 16px 40px; } }
/* Six numbers in one row on a phone broke "check-ins" in two and stacked a label four lines deep: three a row. */
@media (max-width: 600px) { main.club-link .stats > div:not(.sep), main.print .stats > div:not(.sep) { flex: 0 0 33.333%; } }
/* Reports' hero: five or six tiles, three a row on a phone, not six squeezed into one (verifier R1-9). */
@media (max-width: 600px) { .stats.rhero > div:not(.sep):not(.srow) { flex: 0 0 33.333%; } }
/* With the club-tag split leading (run 2 cycle R), four tiles are left: two by two, never three and one alone. */
@media (max-width: 600px) { :is(main.club-link, main.print) .stats:has(> .srow) > div:not(.sep):not(.srow) { flex-basis: 50%; } }
.block { display: block; }

/* The monthly report: printed by the browser as the PDF (2026-09-22). One night per section, never split. */
.print { max-width: 900px; margin: 0 auto; padding: 24px 16px; }
.print h2 { font-size: 18px; margin: 22px 0 8px; }
.print-night { page-break-inside: avoid; break-inside: avoid; }
@media print {
  body { background: #fff; color: #000; }
  .no-print, nav, .rail { display: none !important; }
  .print { padding: 0; max-width: none; }
  .panel, .stats { border: 1px solid #999; background: #fff; }
  a { color: #000; text-decoration: none; }
  /* The app's beige (#9C8A70) is 3.2:1 on white paper; a printed report needs 4.5:1 (loop cycle 9). */
  .muted, table.night th, .lead, footer { color: #555555; }
}

/* phone basics — loop cycle 6 (owner's OK, 2026-10-03). Measured at 390x844 before: the menu took 320 px (38% of
   the screen), 3 of its 13 links sat off-screen, 401 of 475 controls were under 44 px (Apple's minimum for a
   finger), and 7 tables lost the model's name when swiped sideways to reach 50 hidden columns. */
@media (max-width: 900px) {
  /* The top of every team screen (owner's plan v15, screen 2): ☰ on the left, the wordmark in the centre, nothing
     else — the page names its club or subject once, in its own title. */
  .rail { display: grid; grid-template-columns: 48px minmax(0, 1fr) 48px; align-items: center; gap: 10px; padding: 10px 16px; }
  .rail .wordmark { grid-column: 2; grid-row: 1; text-align: center; font-size: 12px; letter-spacing: 0.3em; }
  .rail .tracked { display: none; }
  .menu-open { grid-column: 1; grid-row: 1; display: inline-flex; align-items: center; justify-content: center; width: 48px; height: 48px;
               border: 1px solid var(--edge); border-radius: 12px; cursor: pointer; }
  .menu-open .bars { display: inline-flex; flex-direction: column; gap: 5px; }
  .menu-open .bars i { display: block; width: 20px; height: 1.5px; background: var(--ivory); }
  .menu-toggle:focus-visible + .menu-open { outline: 2px solid var(--gold); outline-offset: 2px; }
  .menu-open { -webkit-tap-highlight-color: transparent; }
  .menu-toggle:checked + .menu-open { border-color: var(--gold); background: var(--card); }
  .menu-body { display: none; grid-column: 1 / -1; flex-direction: column; gap: 16px; padding: 4px 0 10px; }
  .menu-toggle:checked ~ .menu-body { display: flex; }
  /* Owner, 2026-10-12: the menu opened above the page and stayed open, where he had left it, as he slid down. The bar
     stays at the top, so ☰ is always one tap away; the open menu covers the page under it, scrolls on its own, and
     the page behind stays still. Under the add sheet's backdrop (z-index 10). */
  .rail { position: sticky; top: 0; z-index: 9; background: var(--bg); }
  .menu-toggle:checked ~ .menu-body { position: fixed; top: 69px; left: 0; right: 0; bottom: 0; overflow-y: auto;
    overscroll-behavior: contain; background: var(--bg); padding: 12px 16px 24px; border-top: 1px solid var(--card); }
  /* Only the root is locked: overflow on body as well makes body the bar's scroll box, and the sticky bar (with ☰,
     the way to close) slides away out of sight. */
  html:has(.menu-toggle:checked) { overflow: hidden; }
  /* A page that opens on one of its parts (#club-consul, #m-12, #set-aside) lands it below the bar, not under it
     (verifier V-1, M1): the bar is 69 px; 8 px of air. On the target only: a scroll-padding on html made opening the
     menu jump the page to the top, the browser scrolling the focused ☰ checkbox (in the bar, at 0) out of the padded
     strip. */
  :target { scroll-margin-top: 77px; }
  /* A control reached by Tab or VoiceOver lands below the bar too (review run 3, R6). In the page only (section.main;
     the admin pages have no <main>, verifier V3-1 M4): the ☰ box sits in the bar itself, and a margin on it is the
     jump described above. */
  .main :focus { scroll-margin-top: 77px; }
  /* With the menu open a tap anywhere on the bar outside ☰ closes it; iPhone sends that tap to the page only to
     something that looks tappable (V-1, L3). */
  .rail:has(.menu-toggle:checked) { cursor: pointer; }
  .rail .group { flex-direction: column; flex-wrap: nowrap; overflow: visible; gap: 2px; }
  .rail .group .label { display: block; padding: 0 12px 2px; }
  .rail a { min-height: 44px; padding: 10px 12px; border: 0; border-radius: 10px; white-space: normal; }
  .rail form { margin-left: 0; }
  .btn-small, .btn-line, .btn-fill, .chip { min-height: 44px; }
  .btn-small, .btn-line, .chip { height: auto; }
  /* The history buttons' own min-height comes later in the file: one class more to keep the 44 px target. */
  .msgcard .msg-history .btn-small { min-height: 44px; }
  /* The Who and Woman / Man buttons: 44 px to tap on a phone (step 3). Their own rules come later in the file: one
     element more here, so these win. */
  .sheet .seg button, form.gmark .seg .btn-small, .sheet .pk-sort select { min-height: 44px; }
  .field input, select, textarea, input:not([type="checkbox"]):not([type="radio"]):not([type="hidden"]) { min-height: 44px; }
  input[type="file"] { padding: 10px 0; }
  /* The menu's own checkbox stays out of sight and out of reach; its label is the button. */
  input[type="checkbox"]:not(.menu-toggle) { width: 24px; height: 24px; }
  label:has(> input[type="checkbox"]) { display: inline-flex; align-items: center; gap: 10px; min-height: 44px; }
  details > summary { padding: 13px 0; }
  /* A quiet text link that stands for an action ("Delete her data…") keeps its look but gets a finger's height. */
  a.tap { display: inline-flex; align-items: center; min-height: 44px; }
  /* A link inside a sentence ("Fix the connection", the walk-ins' handles) was 18–22 px tall (run 2, P191). On phones
     its line is 46 px tall and its padding fills 44 px of it, so a finger finds it, its hit area stays inside its own
     line, and it still wraps like the words around it. Tried first: an invisible ::after layer, which reached into the
     line above and opened the neighbour's link (cycle K verifier, F1); then an inline-flex box, which cannot break
     across lines, so a long link took a whole line and pushed its full stop onto the next (verifier K2, G1).
     1.4em: Jost's content height is 1.43–1.47em, so the padded fragment is 44–45 px. */
  section.main :is(p, dd, .notice, .warn, .srow .l2 > span) > a:is(:not([class]), .gold) { line-height: 46px; padding-block: calc((44px - 1.4em) / 2); }
  /* The Stories row's handle is a flex item, not a word in a sentence: a 44 px box (F6). */
  section.main .srow .l1 > a.who { display: inline-flex; align-items: center; min-height: 44px; }
}
/* Every team table becomes one card per row: the first cell (the model, the night) on top, then each value with
   its column's name, which views/table-labels.js copies onto the cells. Nothing is reached by swiping. */
@media (max-width: 600px) {
  .panel { padding: 4px 6px; }
  table.night, table.night tbody, table.night tr, table.night td { display: block; width: auto; }
  table.night thead { display: none; }
  table.night tr { padding: 12px 10px; border-bottom: 1px solid var(--line-soft); }
  table.night td { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; padding: 5px 0; border: 0; text-align: right; }
  /* A number cell on a phone card is right-aligned like every value; `td.num`'s centring outranked the rule above and
     put a number over its note mid-row (run 2 cycle Q, verifier Q5-2). */
  table.night td.num { text-align: right; }
  table.night td::before { content: attr(data-label); flex: 0 0 auto; max-width: 45%; color: var(--muted); font-size: 13px; text-align: left; }
  table.night td[data-label=""] { justify-content: flex-start; flex-wrap: wrap; text-align: left; }
  table.night td[data-label=""]::before, table.night td:first-child::before { content: none; }
  table.night td:first-child { display: block; padding-bottom: 8px; font-size: 17px; text-align: left; }
  /* A link alone in a cell (her @handle, a night, "CSV") is the thing to tap: give it a finger's height. */
  table.night td a { display: inline-flex; align-items: center; justify-content: center; min-height: 44px; min-width: 44px; }
  /* A form in a card ("Match to" + Match) wraps, and its list shrinks to the card instead of its longest option. */
  table.night td form.inline { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 8px; min-width: 0; }
  table.night td select { max-width: 100%; min-width: 0; }
}

/* ---- The list row (loop cycle 10, from Stripe, Linear and Material lists). A table on a computer; on a phone
   each person is two lines: who + the number on the right, then when + one word for the state on the right.
   Everything rare is folded into "Details". `table.rows` is not `table.night`, so it gets no generic card. ---- */
.vh { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.chip .n { margin-left: 7px; color: var(--dim); font-variant-numeric: tabular-nums; }
.chip.on .n { color: var(--gold); }
/* Rows are a grid with the same columns on every row, so values line up like a table and a row can open her
   night underneath at full width (no floating box to clip, nothing pushing the page sideways). */
table.rows, table.rows thead, table.rows tbody { display: block; }
table.rows { font-variant-numeric: tabular-nums; }
table.rows tr { display: grid; grid-template-columns: minmax(150px, 2.2fr) minmax(max-content, 0.9fr) minmax(max-content, 0.9fr) minmax(max-content, 0.9fr) minmax(136px, 1.5fr) minmax(max-content, 1.2fr) minmax(max-content, 1fr) minmax(max-content, 0.6fr) 74px; column-gap: 20px; align-items: center; padding: 12px 14px; border-bottom: 1px solid #241810; }
/* On a wide screen the columns belong to the table and every row takes them (`subgrid`, run 2 cycle P, verifier F3):
   with a grid per row, a column sized to its words came out wider in one row than in the next, and each header sat
   up to 53 px right of its values. Only on screen above the switch, and only where subgrid exists: the two-line
   layout, paper (a page can be wider than the switch: verifier N2) and an older browser keep the grid per row. */
@supports (grid-template-columns: subgrid) {
  @media screen and (min-width: 1261px) {
    table.rows { display: grid; grid-template-columns: minmax(150px, 2.2fr) minmax(max-content, 0.9fr) minmax(max-content, 0.9fr) minmax(max-content, 0.9fr) minmax(136px, 1.5fr) minmax(max-content, 1.2fr) minmax(max-content, 1fr) minmax(max-content, 0.6fr) 74px; column-gap: 20px; }
    table.rows thead, table.rows tbody { display: contents; }
    table.rows tr { grid-column: 1 / -1; grid-template-columns: subgrid; }
  }
}
/* No column narrower than its words, and 20 px between columns (run 2 cycle P): at 1101 "10:02 pm10:10 pm" ran
   together, "Followers" and "Arrived" read as one header, "Story" and "Club tag" too, and "Not asked" broke in two. */
table.rows td.r-desk { white-space: nowrap; }
/* "Nobody here matches …" spans the row: a grid ignores colspan, and the line sat squeezed in Model's column. */
table.rows td[colspan] { grid-column: 1 / -1; }
/* A long handle with no break (verifier F6) wraps in its own column instead of widening it. */
table.rows td.r-who a, .tscroll table.night td:first-child a { overflow-wrap: anywhere; }
table.rows thead tr { padding-top: 0; border-bottom-color: var(--line-soft); }
table.rows th, table.rows td { display: block; padding: 0; border: 0; min-width: 0; }
table.rows th { text-align: left; font-weight: 400; font-size: 12.5px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--muted); line-height: 1.3; overflow-wrap: anywhere; }
table.rows th.num { text-align: right; }
table.rows td { font-size: 15px; color: var(--sand); }
table.rows .num { text-align: right; white-space: nowrap; }
.r-who a { font-size: 16px; }
/* 44 px to tap (cycle 6's floor) without making the row taller: the padding is taken back by the margin. */
.r-who a, .r-pop dd a { display: inline-block; padding-block: 11px; margin-block: -11px; }
.r-sub, .r-flag { font-size: 12.5px; color: var(--muted); margin-top: 2px; }
.pill { display: inline-flex; align-items: center; gap: 7px; height: 26px; padding: 0 11px; border-radius: 999px; font-size: 13px; white-space: nowrap; }
.pill .dot { width: 7px; height: 7px; border-radius: 50%; flex: none; }
.pill.tagged { background: var(--gold); color: var(--bg); }
.pill.tagged .dot { background: var(--bg); }
.pill.untagged { border: 1px solid var(--gold); color: var(--gold-bright); }
.pill.untagged .dot { background: var(--gold); }
.pill.reading, .pill.stuck { border: 1px dashed var(--dim); color: var(--sand); }
.pill.reading .dot, .pill.stuck .dot { border: 1.5px solid var(--sand); width: 8px; height: 8px; }
/* Run 2 (P028): "Tag not known" is a badge like the others, outlined in grey, not loose grey text. */
.pill.unknown, .pill.marked { border: 1px solid var(--dim); color: var(--sand); }
.pill.unknown .dot, .pill.marked .dot { display: none; }
td.r-state form.inline button { margin: 0 !important; }
td.r-more { text-align: right; white-space: nowrap; }
td.r-more:has(details[open]) { grid-column: 1 / -1; }
.r-fold > summary { list-style: none; cursor: pointer; display: inline-flex; align-items: center; gap: 8px; min-height: 44px; color: var(--muted); font-size: 14px; }
.r-fold > summary::-webkit-details-marker { display: none; }
.r-fold > summary::after { content: ''; width: 6px; height: 6px; border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor; transform: translateY(-2px) rotate(45deg); flex: none; }
.r-fold[open] > summary::after { transform: translateY(2px) rotate(-135deg); }
.r-fold > summary:hover, .r-fold[open] > summary { color: var(--gold); }
/* Landing on a story's Try again (Needs you, cycle O): 140 px of the page above the line keep her row's name and
   story in view, so the button reads as hers. */
.reread-at { scroll-margin-top: 140px; }
.r-line { display: none; }
.r-pop { max-width: 640px; margin: 6px 0 4px auto; padding: 4px 18px 14px; border-radius: 14px; border: 1px solid var(--line); background: var(--card); text-align: left; white-space: normal; }
dl.kv { display: grid; grid-template-columns: auto minmax(0, 1fr); margin: 0; }
dl.kv dt, dl.kv dd { margin: 0; padding: 10px 0; border-bottom: 1px solid var(--line-soft); font-size: 14px; }
dl.kv dt { color: var(--muted); padding-right: 16px; white-space: nowrap; }
dl.kv dd { color: var(--ivory); min-width: 0; }
.r-actions { display: flex; justify-content: flex-end; padding-top: 12px; }
/* At 1260 px and below nine columns do not fit: each person becomes two lines. (Run 2 cycle P measured 1,261 px for them
   with 20 px between columns and the widest words each can hold — "not connected", "Not needed", "Mark posted",
   "999.9k"; at the old 1100 switch Score ran into Details, and at 1181 the panel scrolled sideways: verifier N1.) */
@media (max-width: 1260px) {
  table.rows thead { display: none; }
  table.rows tr { grid-template-columns: minmax(0, 1fr) auto; column-gap: 12px; padding: 10px 8px 4px; border-bottom-color: var(--line-soft); }
  table.rows td.r-desk, .r-sub, .r-label { display: none; }
  td.r-who { grid-column: 1; grid-row: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; align-self: center; }
  td.r-who .r-flag { white-space: normal; }
  td.r-trail { grid-column: 2; grid-row: 1; align-self: center; font-size: 15px; }
  /* Line two is the tap target for her night, beside the pill. Opened, her night takes the whole width and the
     pill stays over the line's right end, so only then does the line leave it room. */
  td.r-more { grid-column: 1; grid-row: 2; position: static; width: auto; min-width: 0; text-align: left; }
  td.r-more:has(details[open]) { grid-column: 1 / -1; }
  td.r-state { grid-column: 2; grid-row: 2; align-self: start; justify-self: end; margin-top: 9px; position: relative; z-index: 1; }
  td.r-state form.inline { margin-top: -9px; }
  .r-fold > summary { display: flex; width: 100%; gap: 6px; font-size: 13px; }
  .r-fold[open] > summary { padding-right: 150px; }
  .r-line { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
  .r-pop { max-width: none; margin: 2px 0 10px; }
  /* The foot's note on the score column's dash: a phone shows the words in the fold, no dash to explain. */
  .r-dash-note { display: none; }
}
/* On paper the rows are the full table again, black on white, at every page width: paper never takes the screen's
   shared columns above, so this undoes the two-line layout (code review, cycle 10) and builds its own rows. */
@media print {
  table.rows thead { display: block; }
  table.rows tr { grid-template-columns: minmax(0, 2.2fr) repeat(3, minmax(0, 0.9fr)) minmax(0, 1.5fr) minmax(0, 1.2fr) minmax(0, 1fr) minmax(0, 0.6fr); column-gap: 12px; border-bottom-color: #999; }
  table.rows td, table.rows td *, table.rows th { color: #000; }
  /* Her night's heading is for a screen reader beside a button paper does not have; as a ninth cell it narrowed the
     header's columns against the rows'. The headings fit their columns on an A4 page (FOLLOWERS ran into ARRIVED). */
  table.rows thead th:last-child { display: none; }
  table.rows th { font-size: 10px; letter-spacing: 0.03em; }
  table.rows td.r-desk, table.rows .r-sub { display: block; }
  .r-dash-note { display: inline; }
  table.rows td.r-who, table.rows td.r-trail, table.rows td.r-state { grid-column: auto; grid-row: auto; margin: 0; justify-self: stretch; }
  table.rows td.r-more, table.rows td.r-state form { display: none; }
  table.rows .pill { color: #000; background: none; border: 1px solid #000; height: auto; padding: 1px 6px; font-size: 11px; white-space: normal; }
}

/* Loop cycle 11: who she is, as badges — the word for the habit, the strength for how often (1 dashed and faint,
   2–3 outlined, 4+ filled). Gold for what the club wants, terracotta for what it does not. */
[hidden] { display: none !important; }
.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.bdg { display: inline-flex; align-items: center; gap: 5px; height: 24px; padding: 0 8px 0 6px; border-radius: 999px; font-size: 12.5px; line-height: 1; white-space: nowrap; border: 1px solid currentColor; flex: none; }
.bdg svg { width: 14px; height: 14px; flex: none; }
.bdg.good { color: var(--gold); } .bdg.bad { color: var(--warn); }
.bdg.s1 { opacity: .62; border-style: dashed; }
.bdg.s3.good { background: var(--gold); color: var(--bg); border-color: var(--gold); }
.bdg.s3.bad { background: var(--warn); color: var(--bg); border-color: var(--warn); }
.bdg i { font-style: normal; font-variant-numeric: tabular-nums; opacity: .85; }

/* The "Add models" sheet: over the list, which stays behind dimmed (Instagram's New message). */
html.sheet-on, html.sheet-on body { overflow: hidden; }
.scrim { position: fixed; inset: 0; background: rgba(8, 5, 3, .62); z-index: 10; }
.sheet { position: fixed; left: 0; right: 0; top: 150px; bottom: 0; z-index: 11; margin: 0 auto; max-width: 640px; background: var(--bg); border-radius: 18px 18px 0 0; border: 1px solid var(--line); border-bottom: 0; padding: 8px 16px 0; display: flex; flex-direction: column; gap: 14px; }
@media (min-width: 900px) { .sheet { top: 8vh; } }
.sheet .grab { flex: none; width: 40px; height: 5px; border-radius: 3px; background: var(--edge); align-self: center; }
.sh-head { flex: none; display: flex; justify-content: space-between; align-items: center; min-height: 44px; }
.sh-head b { font-weight: 500; font-size: 18px; color: var(--ivory); }
.linkbtn { background: none; border: 0; padding: 0 4px; min-height: 44px; color: var(--gold); font: inherit; font-size: 15px; cursor: pointer; }
.pk-chips { flex: none; display: flex; flex-wrap: wrap; gap: 8px; max-height: 92px; overflow-y: auto; }
.pk-chips:empty { display: none; }
.pk-chip { display: inline-flex; align-items: center; gap: 4px; min-height: 36px; padding: 0 6px 0 14px; border-radius: 999px; background: var(--card); border: 1px solid var(--edge); font: inherit; font-size: 14px; color: var(--ivory); cursor: pointer; }
.pk-chip i { font-style: normal; width: 24px; height: 24px; display: inline-flex; align-items: center; justify-content: center; color: var(--muted); font-size: 16px; }
.pk-search { flex: none; width: 100%; min-height: 48px; padding: 0 14px; border: 1px solid var(--gold); border-radius: 10px; background: var(--card); color: var(--ivory); font: inherit; font-size: 16px; }
/* The browser's own clear button is blue on Chrome; the sheet keeps its palette. */
.pk-search::-webkit-search-cancel-button { -webkit-appearance: none; display: none; }
/* Who and Sort in the sheet (step 3): one line when it fits, the sort under it on a narrow phone. */
.pk-tools { flex: none; display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; }
.seg { display: inline-flex; border: 1px solid var(--edge); border-radius: 999px; overflow: hidden; }
.seg button { min-height: 36px; padding: 0 14px; background: none; border: 0; color: var(--sand); font: inherit; font-size: 14px; cursor: pointer; }
.seg button + button { border-left: 1px solid var(--edge); }
.seg button[aria-pressed="true"] { background: var(--gold); color: var(--bg); }
.seg button:focus-visible { outline: 2px solid var(--gold-bright); outline-offset: -3px; }
.pk-sort { display: inline-flex; align-items: center; gap: 6px; font-size: 14px; color: var(--muted); }
.pk-sort select { min-height: 36px; max-width: 100%; padding: 0 8px; border: 1px solid var(--edge); border-radius: 8px; background: var(--card); color: var(--ivory); font: inherit; font-size: 14px; }
/* Woman / Man on her page and on Models → Not marked yet (step 3). */
.gmark { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 10px; margin: 6px 0 14px; }
.gmark .k { font-size: 14px; color: var(--muted); }
.gmark .seg .btn-small { border: 0; border-radius: 0; height: auto; min-height: 36px; }
.gmark .seg .btn-small + .btn-small { border-left: 1px solid var(--edge); }
.gmark .seg .btn-small[aria-pressed="true"] { background: var(--gold); color: var(--bg); }
ul.mrows > li > .gmark { margin: -4px 16px 14px; }
.sh-body { flex: 1 1 auto; min-height: 0; overflow-y: auto; display: flex; flex-direction: column; gap: 10px; padding-bottom: 12px; }
/* Each section keeps its full height so .sh-body scrolls (owner, 2026-10-12: Here before / Never here would not
   scroll): a flex child with overflow hidden (ul.lrows) shrinks to the space left and clips its own rows. */
.sh-body > * { flex: none; }
.sh-body .none { margin: 6px 0; font-size: 14px; color: var(--muted); }
/* The results under the Who / Sort row, in the same scroll (step 3, verifier S3-1 M1: a fixed row above them left
   34 px of results on a 360 x 640 phone with 4 picks). */
.sh-res { display: flex; flex-direction: column; gap: 10px; }
.sh-res > * { flex: none; }
.pk-sec { display: flex; justify-content: space-between; align-items: center; min-height: 32px; font-size: 14px; color: var(--champagne); }
.pk-sec .linkbtn { min-height: 32px; font-size: 14px; }
ul.lrows { list-style: none; margin: 0; padding: 0; background: var(--card); border: 1px solid var(--line-soft); border-radius: 14px; }
ul.lrows > li + li { border-top: 1px solid var(--line-soft); }
ul.pk label { position: relative; display: grid; grid-template-columns: 40px minmax(0, 1fr) auto 32px; gap: 4px 12px; align-items: center; padding: 12px 14px; cursor: pointer; }
ul.pk label:has(input:focus-visible) { outline: 2px solid var(--gold-bright); outline-offset: -2px; border-radius: 12px; }
ul.pk input[type=checkbox] { position: absolute; opacity: 0; width: 1px; height: 1px; }
ul.pk .ava { grid-column: 1; grid-row: 1 / 3; width: 40px; height: 40px; border-radius: 50%; background: #3A2C1F; color: var(--champagne); display: flex; align-items: center; justify-content: center; font-size: 16px; }
.ava.top { box-shadow: 0 0 0 2.5px var(--gold), 0 0 0 4px rgba(201, 164, 92, .25); color: var(--gold-bright); }
.ava.ban { box-shadow: 0 0 0 2.5px var(--warn); color: var(--warn); }
ul.pk .lh { grid-column: 2; grid-row: 1; min-width: 0; font-size: 16px; color: var(--gold); }
.lh2 { display: flex; align-items: center; gap: 10px; min-width: 0; }
.lh2 .hd { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
ul.pk .lf { grid-column: 3; grid-row: 1; text-align: right; font-size: 15px; color: var(--ivory); }
ul.pk .ls { grid-column: 2 / 4; grid-row: 2; min-width: 0; font-size: 13.5px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
ul.pk .ls.bdgs { display: flex; gap: 6px; align-items: center; }
ul.pk .ls .more { font-size: 12.5px; color: var(--muted); flex: none; }
ul.pk .ls .why { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
ul.pk .tick { grid-column: 4; grid-row: 1 / 3; width: 26px; height: 26px; border-radius: 50%; border: 1.5px solid var(--edge); justify-self: end; position: relative; }
ul.pk input:checked ~ .tick { background: var(--gold); border-color: var(--gold); }
ul.pk input:checked ~ .tick::after { content: ""; position: absolute; left: 8px; top: 4px; width: 6px; height: 11px; border: solid var(--bg); border-width: 0 2px 2px 0; transform: rotate(45deg); }
.fold-ban { border: 1px dashed var(--line); border-radius: 14px; font-size: 14px; color: var(--muted); }
.fold-ban summary { min-height: 48px; display: flex; align-items: center; padding: 0 16px; cursor: pointer; }
.fold-ban summary b { color: var(--warn); font-weight: 400; }
.fold-ban ul.lrows { border: 0; border-top: 1px dashed var(--line); border-radius: 0 0 14px 14px; }
.sheet .dock { flex: none; padding: 10px 0 max(16px, env(safe-area-inset-bottom)); background: var(--bg); }
.sheet .dock .big { width: 100%; min-height: 52px; border-radius: 12px; border: 0; background: var(--gold); color: var(--bg); font: inherit; font-size: 16px; font-weight: 500; cursor: pointer; }
.sheet .dock .big:disabled { background: var(--card); color: var(--dim); cursor: default; }

/* The night list as rows (loop cycle 11): the list first; each model two lines — handle and who she is, her
   followers; where she is in words, and one state. Tapping the row opens the ways to send, her page, Remove. */
.backlink { display: inline-flex; align-items: center; gap: 10px; min-height: 44px; font-size: 15px; color: var(--gold); width: fit-content; }
.chev { display: inline-block; width: 8px; height: 8px; border-left: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor; transform: rotate(45deg); }
.nhead-list { margin: 2px 0 0; font-size: 14px; color: var(--muted); }
.addbar { display: flex; gap: 8px; width: 100%; max-width: 720px; padding: 0; border: 0; background: none; font: inherit; cursor: pointer; text-align: left; }
.addbar .in { flex: 1; min-height: 48px; display: flex; align-items: center; padding: 0 14px; border: 1px solid var(--edge); border-radius: 10px; color: var(--dim); font-size: 15px; }
.addbar .go { min-height: 48px; padding: 0 18px; border-radius: 10px; background: var(--gold); color: var(--bg); display: flex; align-items: center; font-size: 15px; font-weight: 500; }

/* The event (night) page top, screen 4 (drawing 4, revised 2026-10-08): ‹ Events and More, the date between
   its two arrows on the corners, the club line, the wide Open the list button. Capped like the list rows, so on
   a computer the arrows stay beside the date instead of at the two ends of the screen. */
.chev.r { transform: rotate(-135deg); }
.nhead { display: flex; flex-direction: column; gap: 4px; max-width: 720px; }
.nhead-top { display: flex; justify-content: space-between; align-items: center; gap: 12px; }
.more { position: relative; }
.more summary { list-style: none; min-height: 44px; display: inline-flex; align-items: center; padding: 0 16px; border: 1px solid var(--line); border-radius: 999px; color: var(--sand); font-size: 14px; cursor: pointer; }
.more summary::-webkit-details-marker { display: none; }
.more-pop { position: absolute; right: 0; top: 50px; z-index: 5; width: max-content; min-width: 180px; max-width: min(300px, calc(100vw - 32px)); background: var(--card); border: 1px solid var(--line); border-radius: 12px; padding: 6px; display: flex; flex-direction: column; }
.more-pop a, .more-pop button { min-height: 44px; display: flex; align-items: center; padding: 8px 12px; color: var(--ivory); font: inherit; font-size: 15px; text-align: left; background: none; border: 0; border-radius: 8px; cursor: pointer; }
.night-date { display: grid; grid-template-columns: 44px minmax(0, 1fr) 44px; align-items: center; gap: 8px; margin-top: 6px; }
.night-date h1 { text-align: center; font-size: 19px; line-height: 1.2; margin: 0; }
.night-step { width: 44px; height: 44px; display: inline-flex; align-items: center; justify-content: center; border: 1px solid var(--line); border-radius: 50%; color: var(--sand); }
.night-step .chev { margin-left: 3px; }
.night-step .chev.r { margin: 0 3px 0 0; }
.night-step.off { border-color: var(--line-soft); color: var(--edge); opacity: .5; }
.nhead .nhead-list { text-align: center; }
.list-btn { margin-top: 12px; display: flex; align-items: center; justify-content: center; min-height: 48px; border-radius: 12px; border: 1px solid var(--gold); color: var(--gold); font-size: 15.5px; }
ul.lrows { max-width: 720px; overflow: hidden; }
.lrow > summary { list-style: none; display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 6px 12px; align-items: center; padding: 14px 16px; cursor: pointer; }
.lrow > summary::-webkit-details-marker { display: none; }
.lrow[open] > summary { background: #33220F; }
.lrow .lh { font-size: 16px; color: var(--gold); }
.lrow .lf { text-align: right; font-size: 15px; color: var(--ivory); }
.lrow .ls { font-size: 13.5px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.lrow .lact { justify-self: end; }
.lh2 .minis { display: inline-flex; gap: 8px; flex: none; }
.mini { display: inline-flex; align-items: center; gap: 3px; font-size: 12.5px; flex: none; }
.mini svg { width: 14px; height: 14px; }
.mini.good { color: var(--gold); } .mini.bad { color: var(--warn); } .mini.s1 { opacity: .6; }
.pill.now { background: var(--gold); color: var(--bg); } .pill.now .dot { background: var(--bg); }
.pill.going { border: 1px solid var(--gold); color: var(--gold-bright); } .pill.going .dot { background: var(--gold); }
.pill.sent { color: var(--muted); padding: 0; }
/* A waiting state is a word, not a button (run 2, P054): no outline on To send. */
.pill.unsent { color: var(--sand); padding: 0; }
.lopen { display: flex; flex-direction: column; gap: 10px; padding: 4px 16px 16px; border-top: 1px dashed var(--line-soft); }
.lopen .about { margin: 8px 0 0; font-size: 13.5px; color: var(--muted); }
.warn-t { color: var(--warn); }
.lopen .btns { display: grid; grid-template-columns: repeat(auto-fit, minmax(0, 1fr)); gap: 8px; }
.lopen .btns a, .lopen .btns button { min-height: 44px; display: flex; align-items: center; justify-content: center; border: 1px solid var(--edge); border-radius: 10px; background: none; color: var(--ivory); font: inherit; font-size: 14px; cursor: pointer; }
/* Not `.main`: that is the page column, and its padding reached this button (cycle K verifier, F7). */
.lopen .btns .primary { background: var(--gold); border-color: var(--gold); color: var(--bg); font-weight: 500; }
.lopen p { margin: 0; font-size: 12.5px; color: var(--dim); }
.lmore { display: flex; justify-content: space-between; align-items: center; gap: 12px; }
.lmore a { font-size: 14px; display: inline-flex; align-items: center; min-height: 44px; }
.lmore .rm { background: none; border: 0; padding: 0; min-height: 44px; font: inherit; font-size: 13.5px; color: var(--muted); cursor: pointer; }
.extra { margin: 0; font-size: 14px; color: var(--muted); max-width: 720px; }
.fold { max-width: 720px; }
.fold > summary { cursor: pointer; color: var(--sand); font-size: 14.5px; min-height: 44px; display: flex; align-items: center; gap: 12px; list-style: none; }
.fold > summary::-webkit-details-marker { display: none; }
.fold > summary::before { content: ""; flex: none; width: 7px; height: 7px; border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor; transform: rotate(-45deg); }
.fold[open] > summary::before { transform: rotate(45deg); }
.fold.panel { padding: 0 16px; }
.fold.panel[open] { padding-bottom: 16px; }
.msgcard { max-width: 720px; border: 1px solid var(--line); border-radius: 14px; padding: 14px 16px; display: flex; flex-direction: column; gap: 10px; background: var(--card); }
.msgcard .mc-h { font-size: 16px; color: var(--ivory); }
/* Folded to one line unless a warning needs it (run 2, P046); a <details> is a block, its body the column. */
details.msgcard { display: block; }
details.msgcard > summary { cursor: pointer; list-style: none; display: flex; flex-direction: column; gap: 2px; }
details.msgcard > summary::-webkit-details-marker { display: none; }
.msgcard .mc-first { font-size: 13.5px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
details.msgcard[open] .mc-first { display: none; }
.msgcard .mc-body { display: flex; flex-direction: column; gap: 10px; margin-top: 10px; }
.msgcard .warn form { margin-top: 8px; }
/* A long link in the message breaks where it must, not the page (verifier V3-2 L5: 935 px wide at 390). */
.msgcard .pre { font-size: 14px; color: var(--sand); white-space: pre-line; line-height: 1.5; overflow-wrap: anywhere; }
.msgcard .warn { font-size: 13.5px; color: var(--gold-bright); overflow-wrap: anywhere; }
/* Put back / Undo under Edit: up to four named buttons, each on its own line when it must, labels free to wrap
   (verifier V3-5 M1: "Undo The Yang's Club 94’s last Put back" widened the page at 360–390 px). */
.msg-history { margin-top: 10px; display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.msg-history .btn-small { white-space: normal; text-align: left; height: auto; min-height: 38px; max-width: 100%; }
.msgcard .acts { display: flex; gap: 16px; }
/* New text (2026-10-12): the written version in the editor, filled in for the night, before it is saved. */
.msgcard a.btn-small { text-decoration: none; }
.msgcard .draft { display: flex; flex-direction: column; gap: 6px; margin-top: 12px; padding: 12px 14px; border: 1px solid var(--line-soft); border-radius: 10px; }
.msgcard .draft p { margin: 0; }
/* The models just added or put back (run 3, F3): the page opens on them, and they are marked till the next page. */
/* --line-soft, one step above an open row's #33220F: --card was the list's own colour, and the mark did not show
   (browser walk at 390 px). */
.lrows li.just > .lrow > summary { background: var(--line-soft); }
ul.mrows > li.just { background: var(--line-soft); }
table.rows tr.just, table.rows tr.just > td { background: var(--line-soft); }
.msgcard details > summary { cursor: pointer; color: var(--gold); font-size: 14px; }

/* One link per night (loop cycle 11): the requests that wait for the team, the Send button under the rows,
   and the Send page. */
.reqs { display: flex; flex-direction: column; gap: 8px; max-width: 720px; }
.reqs .mc-h { margin: 0; font-size: 15px; color: var(--champagne); }
ul.lrows > li.req { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 4px 12px; align-items: center; padding: 12px 16px; }
li.req .lh { font-size: 16px; color: var(--gold); }
li.req .ls { grid-column: 1; font-size: 13.5px; color: var(--muted); }
li.req .racts { grid-column: 2; grid-row: 1 / 3; display: flex; align-items: center; gap: 12px; }
li.req .rm { background: none; border: 0; padding: 0; min-height: 44px; font: inherit; font-size: 13.5px; color: var(--muted); cursor: pointer; }
/* Stays at the bottom of the screen while the rows scroll (run 2, P055): it sat a screen below the top. */
.sendall { display: flex; flex-direction: column; align-items: center; justify-content: center; min-height: 52px; max-width: 720px; border-radius: 12px; background: var(--gold); color: var(--bg); font-size: 16px; font-weight: 500;
  padding: 4px 12px; text-align: center; position: sticky; bottom: 12px; z-index: 5; box-shadow: 0 6px 24px rgba(0, 0, 0, .55); }
.sendall .who { font-size: 13px; font-weight: 400; }
/* Once arrival has passed (run 2 cycle V): the night's job is who is here, so sending steps down from the sticky gold
   bar to a plain one where the rows end; it still sends to the same models. */
.sendall.late { position: static; background: transparent; color: var(--gold); border: 1px solid var(--edge); box-shadow: none; }
.sendall.late .when { font-size: 13px; font-weight: 400; color: var(--muted); }
.legend { margin: 0; font-size: 13px; color: var(--muted); max-width: 720px; }
.legend .mini { vertical-align: -2px; }
.nurl { word-break: break-all; color: var(--sand); }
.how { margin: 0; padding-left: 22px; max-width: 720px; display: flex; flex-direction: column; gap: 8px; color: var(--sand); font-size: 15px; line-height: 1.5; }
.how b { color: var(--ivory); font-weight: 500; }
form.dock { display: flex; flex-direction: column; gap: 10px; max-width: 720px; }
form.dock .big { min-height: 52px; border-radius: 12px; border: 1px solid var(--gold); background: var(--gold); color: var(--bg); display: flex; align-items: center; justify-content: center; font: inherit; font-size: 16px; font-weight: 500; cursor: pointer; }
form.dock .big.line { background: transparent; border-color: var(--edge); color: var(--ivory); font-weight: 400; }
form.dock p { margin: 0; text-align: center; }

/* The invitation she opens (loop cycle 11 step 5, the owner's mock): the club's cover, the night's facts in rows,
   the answers side by side at the same size; her answer lit gold. Her own /rsvp link and the night link share it. */
body.phone main.invite { gap: 20px; padding-top: 40px; }
.cover { height: 190px; border-radius: 16px; background: radial-gradient(ellipse 80% 70% at 30% 20%, #5A3A1C 0%, var(--card) 55%, var(--bg) 100%); border: 1px solid var(--line); display: flex; align-items: flex-end; padding: 16px; }
.cover span { font-family: var(--display); font-size: 22px; color: var(--champagne); letter-spacing: .04em; overflow-wrap: anywhere; }
/* The night's or the club's photo (Create an event, screen 3): the club's name stays readable on a dark fade. */
.cover.has-photo { position: relative; overflow: hidden; height: 240px; }
.cover.has-photo img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.cover.has-photo::after { content: ''; position: absolute; inset: 0; background: linear-gradient(to top, rgba(12, 8, 5, .88), rgba(12, 8, 5, 0) 60%); }
.cover.has-photo span { position: relative; z-index: 1; }
.invite-h { font-size: 28px; }
.facts { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--line-soft); }
.facts li { display: grid; grid-template-columns: 104px minmax(0, 1fr); gap: 12px; padding: 11px 0; border-bottom: 1px solid var(--line-soft); font-size: 15px; color: var(--ivory); }
.facts b { font-weight: 300; color: var(--muted); }
.facts span { overflow-wrap: anywhere; }
.facts a { color: var(--gold); }
.three { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
.three.two { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.three button { min-height: 52px; display: flex; align-items: center; justify-content: center; border-radius: 12px; border: 1px solid var(--edge); background: transparent; color: var(--ivory); font: inherit; font-size: 15px; cursor: pointer; padding: 0 6px; }
.three button.on { background: var(--gold); border-color: var(--gold); color: var(--bg); font-weight: 500; }
.three button.suggested { border-color: var(--gold); color: var(--gold); font-weight: 500; }
.count { font-size: 14px; color: var(--muted); }
.okline { display: flex; align-items: center; gap: 10px; font-size: 17px; color: var(--champagne); }
.okline .dot { width: 9px; height: 9px; border-radius: 50%; background: var(--gold); flex: none; }
.said { color: var(--ivory); }
.btn-line2 { display: flex; align-items: center; justify-content: center; min-height: 48px; border-radius: 12px; border: 1px solid var(--edge); color: var(--ivory); font-size: 15px; }
/* Step 4: her sign-up with her first yes. Woman / Man are two big tap targets, the picked one gold; "optional" is
   quieter than the label it qualifies; a typed handle's fields fold under one line so a model we know is not slowed. */
.su-h { font-family: var(--body); font-weight: 500; font-size: 17px; color: var(--ivory); margin: 0; }
.field span i { font-style: normal; color: var(--muted); font-size: 13px; }
.pick2 { border: 0; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
.pick2 legend { padding: 0; margin-bottom: 8px; font-size: 14px; color: var(--gold); }
.pick2 legend i { font-style: normal; color: var(--muted); font-size: 13px; }
.pick2 label { position: relative; min-height: 52px; display: flex; align-items: center; justify-content: center; border-radius: 12px; border: 1px solid var(--edge); color: var(--ivory); font-size: 15px; cursor: pointer; }
.pick2 input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.pick2 label:has(input:checked) { background: var(--gold); border-color: var(--gold); color: var(--bg); font-weight: 500; }
.pick2 label:has(input:focus-visible) { outline: 2px solid var(--gold); outline-offset: 3px; }
.su-new { border-top: 1px solid var(--line-soft); border-bottom: 1px solid var(--line-soft); }
.su-new > summary { min-height: 48px; display: flex; align-items: center; color: var(--gold); font-size: 15px; cursor: pointer; }
.su-new[open] > summary { margin-bottom: 4px; }
.su-new > div { padding-bottom: 16px; }
li.req .su-req { grid-column: 1 / -1; color: var(--sand); }

/* Events, the team's home (owner's plan v15, screen 1; step 2, 2026-10-07). Copied from the approved drawing:
   Needs you in a gold frame, Tonight as one card, Upcoming and Past as tabs, events as two-line rows. */
h2.blk { font-family: var(--body); font-weight: 500; font-size: 13px; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); margin: 0 0 -14px; }
.need { list-style: none; margin: 0; padding: 0; border: 1px solid var(--gold); border-radius: 14px; background: #2A1B10; max-width: 720px; }
.need li + li { border-top: 1px solid var(--line-soft); }
.need a { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 2px 12px; align-items: center; padding: 12px 16px; color: var(--ivory); min-height: 44px; }
.need .t { font-size: 15px; } .need .s { font-size: 13px; color: var(--muted); } .need .go { grid-row: span 2; color: var(--gold); font-size: 14px; }
.tonight a { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 6px 12px; padding: 16px; border: 1px solid var(--line); border-radius: 14px; background: var(--card); color: var(--ivory); max-width: 720px; }
.tonight .d { font-size: 17px; } .tonight .n { font-size: 17px; text-align: right; } .tonight .s { font-size: 13.5px; color: var(--muted); }
/* Run 2 (P002 P004): Tonight's numbers as three cells, and Open in gold, the card's action, not a grey caption. */
.tonight .tn-stats { grid-column: 1 / -1; display: flex; flex-wrap: wrap; gap: 6px 20px; font-size: 14px; color: var(--sand); }
.tonight .tn-stats b { font-weight: 500; font-size: 17px; color: var(--ivory); margin-right: 3px; }
.tonight .tn-note { grid-column: 1 / -1; }
.tonight .go { grid-column: 1 / -1; justify-self: end; display: inline-flex; align-items: center; gap: 6px; color: var(--gold); font-size: 15px; }
.tonight .chev-r { width: 7px; height: 7px; border-top: 1.5px solid currentColor; border-right: 1.5px solid currentColor; transform: rotate(45deg); }
.tonight + .tonight { margin-top: -12px; }
.tabs { display: flex; gap: 4px; border-bottom: 1px solid var(--line); max-width: 720px; }
.tabs a { min-height: 44px; display: inline-flex; align-items: center; padding: 0 16px; color: var(--sand); border-bottom: 2px solid transparent; margin-bottom: -1px; font-size: 15px; }
.tabs a.on { color: var(--ivory); border-color: var(--gold); }
ul.nlist { list-style: none; margin: 0; padding: 0; background: var(--card); border: 1px solid var(--line-soft); border-radius: 14px; max-width: 720px; }
ul.nlist li + li { border-top: 1px solid var(--line-soft); }
ul.nlist a { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 6px 12px; align-items: center; padding: 14px 16px; color: var(--ivory); }
ul.nlist a:hover { background: #33220F; }
/* The hover fill follows the list's rounded corners; overflow: hidden would also clip the focus ring. */
ul.nlist li:first-child a { border-radius: 13px 13px 0 0; } ul.nlist li:last-child a { border-radius: 0 0 13px 13px; }
ul.nlist li:only-child a { border-radius: 13px; }
.nl-date { font-size: 16px; font-weight: 400; } .nl-came { text-align: right; font-size: 16px; }
.nl-sub { font-size: 13.5px; color: var(--muted); min-width: 0; }   /* wraps: "none tagged the …" hid the answer */
.nl-state { justify-self: end; }
.btn-create { display: flex; align-items: center; justify-content: center; min-height: 48px; border-radius: 12px; background: var(--gold); color: var(--bg); font-size: 15px; font-weight: 500; max-width: 720px; }

/* Stories and Unmatched (run 2, cycle C). The Stories answer is three labelled facts (P092); each story is one line
   with the night page's pill grammar — solid gold = tagged, terracotta outline = not, dashed = being read, plain muted
   = not known (P091) — and Unmatched is one card per story with every way out (P099). */
dl.facts { margin: 16px 0 20px; max-width: 720px; }
dl.facts > div { display: contents; }
dl.facts dd { overflow-wrap: anywhere; }
h3 .count { display: block; margin-top: 4px; font-family: var(--body); font-weight: 400; font-size: 14px; color: var(--muted); }
ul.slist { list-style: none; margin: 10px 0 24px; padding: 0; background: var(--card); border: 1px solid var(--line-soft); border-radius: 14px; max-width: 720px; }
ul.slist > li + li { border-top: 1px solid var(--line-soft); }
.srow { padding: 12px 16px; }
.srow .l1, .mcard .mc-top { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 12px; }
.srow .l1 .pill { margin-left: auto; }
/* Scoped to the rows that own it: a bare `.who` also coloured the list's send button names ("@olga.v and @mia.rose",
   `.sendall .who`) gold on its gold fill, 1:1, invisible since cycle C (run 2 re-score audit). The same collision as
   `.how` in cycle K: a short class name styled globally reaches another screen's element of the same name. */
:is(.srow, .mcard) .who { color: var(--gold); font-size: 16px; overflow-wrap: anywhere; min-width: 0; }
:is(.srow, .mcard) .who.muted { color: var(--muted); }
.srow .t, .mcard .t { color: var(--muted); font-size: 13.5px; white-space: nowrap; }
.srow .l2 { display: flex; flex-wrap: wrap; gap: 4px 16px; margin-top: 6px; color: var(--sand); }
.pill.ok { background: var(--gold); color: var(--bg); }
.pill.bad, .pill.warn { border: 1px solid var(--warn); color: var(--warn); }
.pill.wait { border: 1px dashed var(--dim); color: var(--sand); }
.pill.muted { color: var(--muted); padding: 0; }
.mlist { display: grid; gap: 14px; max-width: 720px; margin-top: 16px; }
.mcard { background: var(--card); border: 1px solid var(--line-soft); border-radius: 14px; padding: 14px 16px; }
.mcard.aside { border-style: dashed; margin-top: 10px; }
.mcard p { margin: 6px 0 0; }
.mcard .why { color: var(--ivory); font-size: 15px; line-height: 1.5; }
.mcard .mc-photo { margin-top: 6px; }
form.mc-match { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 10px; margin-top: 12px; }
form.mc-match select { height: 48px; min-width: 0; border-radius: 12px; background: var(--bg); color: var(--ivory); border: 1px solid var(--edge); padding: 0 12px; font: inherit; font-size: 15px; }
form.mc-match :is(.btn, .btn-line) { height: 48px; width: auto; padding: 0 24px; }
form.mc-match :is(.btn, .btn-line):disabled { background: transparent; border: 1px solid var(--edge); color: var(--muted); cursor: not-allowed; }
.mc-actions { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 10px; }
details.setaside { max-width: 720px; margin-top: 24px; }
details.setaside > summary { cursor: pointer; color: var(--sand); padding: 10px 0; min-height: 44px; }

/* The Models list on a phone (run 2, D1, P069–P077): one row per model, each fact beside its word, nothing drawn as
   a dash; the table is for a wide screen. Search on one line, the sort under it. */
.narrow-only { display: none; }
/* The rows up to 1260 px, as on the night page (run 2 cycle P): from 901 the Models table hid Score, its own order,
   behind a sideways scroll, and at 901 seven of its fifteen columns. */
@media (max-width: 1260px) { .wide-only { display: none; } .narrow-only { display: block; } }
.narrow-only[hidden] { display: none; }
/* The Models table and a club's models (run 2 cycle P, their panels marked `tscroll`): one line per cell (dates and
   "2 of 2" stacked in three lines, headers in four), the model's column kept in place while the rest scrolls, and a
   shade at the right edge while more is to the right (a cover that scrolls with the table hides it at the end). */
.tscroll table.night th, .tscroll table.night td { white-space: nowrap; padding-left: 12px; padding-right: 12px; }
.tscroll table.night td:first-child { white-space: normal; min-width: 160px; }
.tscroll table.night td.why { white-space: normal; min-width: 220px; }
.tscroll table.night th:first-child, .tscroll table.night td:first-child { position: sticky; left: 0; z-index: 1; background: #1A120C; box-shadow: 1px 0 0 var(--line-soft); }
/* No side padding: scrolled cells showed in it, left of the column kept in place. The foot note stays in place too. */
.panel.tscroll { padding-left: 0; padding-right: 0; }
.panel.tscroll > .foot { position: sticky; left: 0; }
.panel.tscroll { background: linear-gradient(to right, rgba(26, 18, 12, 0), #1A120C 60%) 100% 0 / 40px 100% no-repeat local,
  radial-gradient(farthest-side at 100% 50%, rgba(0, 0, 0, .75), rgba(0, 0, 0, 0)) 100% 0 / 18px 100% no-repeat scroll, #1A120C; }
/* On paper (with "Background graphics" on) the dark panel and the kept-in-place column outranked the print's white
   panel: black text on near-black, a dark rule down the first column and row lines missing under it (verifier P3-1,
   P3-4). Written after them so it wins. */
@media print {
  .panel.tscroll { background: #fff; }
  .tscroll table.night th:first-child, .tscroll table.night td:first-child { position: static; background: none; box-shadow: none; }
}
.mtools { display: flex; flex-direction: column; gap: 10px; max-width: 720px; }
.mt-q { display: flex; gap: 8px; }
.mt-q input { flex: 1 1 auto; min-width: 0; min-height: 44px; }
.mt-sort { display: flex; align-items: center; gap: 12px; font-size: 14px; color: var(--muted); }
.mt-sort select { flex: 1 1 auto; max-width: 260px; min-height: 44px; }
.mt-all { display: inline-flex; align-items: center; min-height: 44px; width: fit-content; }
.msort { margin: 0; max-width: 720px; }
ul.mrows > li > a.mrow { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 4px 12px; padding: 14px 16px; color: inherit; text-decoration: none; }
.mrow .lh { min-width: 0; font-size: 16px; color: var(--gold); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mrow .lf { text-align: right; font-size: 15px; color: var(--ivory); white-space: nowrap; }
.mrow .k { font-size: 12.5px; color: var(--muted); }
.mrow .ls { grid-column: 1 / -1; display: flex; flex-wrap: wrap; gap: 2px 14px; font-size: 14px; color: var(--sand); }
.mrow .mfs { grid-column: 1 / -1; display: flex; flex-wrap: wrap; gap: 4px 16px; margin-top: 2px; font-size: 14px; color: var(--ivory); }
.mrow .mf { white-space: nowrap; }
.mrow .mwhy { grid-column: 1 / -1; font-size: 13px; color: var(--warn); }

/* A model's page (run 2, D1, P078–P085): her handle as she writes it, tiles that never break a number, the score
   shared out of 100, and Delete drawn as what it does. */
h1.her-handle { font-family: var(--body); font-weight: 500; text-transform: none; overflow-wrap: anywhere; }
.stats .n .of { font-family: var(--body); font-size: 15px; font-weight: 400; color: var(--muted); }
.stats .n { white-space: nowrap; }
/* Its own class: as `.how` it was also the send screen's steps, and its grid split "Tap Share, then Instagram." into
   columns on every phone (cycle K). */
.score-how { max-width: 720px; display: flex; flex-direction: column; gap: 8px; padding: 14px 16px; border: 1px solid var(--line-soft); border-radius: 14px; background: var(--card); color: var(--sand); font-size: 15px; line-height: 1.5; }
.score-how .how-h { margin: 0; font-size: 15px; color: var(--champagne); }
.score-how ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.score-how li { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 0 12px; font-size: 14px; }
.score-how li .w { color: var(--ivory); text-align: right; font-variant-numeric: tabular-nums; }
.score-how li .w .of { color: var(--muted); }
/* Run 2 cycle N: each part's bar is filled to the points she earned of its share; the numbers carry the meaning. */
.score-how li .bar { grid-column: 1 / -1; height: 4px; margin: 4px 0 2px; border-radius: 2px; background: var(--line-soft); overflow: hidden; }
.score-how li .bar i { display: block; height: 100%; background: var(--gold); }
.score-how li .b { grid-column: 1 / -1; font-size: 13px; color: var(--muted); }
/* No score yet / New in a score cell: the body face, quiet, on one line — not the gold display numerals (verifier N2 N10). */
.unscored { font-family: var(--body); font-size: 13px; font-weight: 400; color: var(--muted); white-space: nowrap; letter-spacing: 0; text-transform: none; }
.score-how p { margin: 0; font-size: 13px; color: var(--muted); }
.btn-danger { display: inline-flex; align-items: center; min-height: 44px; padding: 10px 18px; border: 1px solid var(--warn); border-radius: 10px; background: none; color: var(--warn); font: inherit; font-size: 14.5px; cursor: pointer; width: fit-content; }
.danger-zone { max-width: 720px; display: flex; flex-direction: column; gap: 8px; margin-top: 8px; padding-top: 16px; border-top: 1px solid var(--line-soft); }
.danger-zone p { margin: 0; font-size: 13.5px; color: var(--muted); }
/* One column on a phone (run 2, D1): two columns cut the fields' examples ("e.g. +66 81 234 5…"), P075's flaw again. */
@media (max-width: 600px) { .grid2 { grid-template-columns: minmax(0, 1fr); } }

/* A club's page (run 2, D2a, P109–P116): the range as one control with the one on filled; three numbers lead; the
   models as compact rows on a phone; the nights a small table on every screen; the reports a list of links. */
.seg { display: flex; max-width: 520px; border: 1px solid var(--edge); border-radius: 12px; overflow: hidden; }
.seg a { flex: 1 1 0; min-height: 44px; display: flex; align-items: center; justify-content: center; padding: 0 10px; font-size: 14.5px; color: var(--sand); text-align: center; }
.seg a + a { border-left: 1px solid var(--edge); }
.seg a[aria-current="true"] { background: var(--gold); color: var(--bg); font-weight: 500; }
.range-line { margin: 0; }
.dates-form { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 10px; max-width: 520px; }
.dates-form .field { flex: 1 1 0; min-width: 0; }
.dates-form .field input { padding: 0 12px; min-width: 0; }
@media (max-width: 600px) { .dates-form button { flex: 1 0 100%; justify-content: center; text-align: center; } }
.stats.lead3 .n { font-size: 26px; }
.relation { margin: 0; font-size: 15px; color: var(--ivory); max-width: 720px; }
table.ctable { width: 100%; border-collapse: collapse; }
table.ctable th { font-weight: 400; font-size: 12.5px; color: var(--muted); text-align: left; padding: 10px 8px; border-bottom: 1px solid var(--line-soft); }
table.ctable td { padding: 10px 8px; font-size: 14.5px; border-bottom: 1px solid #241810; vertical-align: top; }
table.ctable tr:last-child td { border-bottom: 0; }
table.ctable .num { text-align: right; }
table.ctable .sub { display: block; font-size: 12px; color: var(--muted); white-space: nowrap; }
ul.golinks > li > a { display: flex; align-items: center; justify-content: space-between; min-height: 48px; padding: 0 16px; color: var(--ivory); }
table.ctable td:first-child { white-space: nowrap; }
@media (max-width: 600px) { table.ctable th, table.ctable td { padding: 10px 5px; } table.ctable th:first-child, table.ctable td:first-child { padding-left: 12px; } table.ctable th:last-child, table.ctable td:last-child { padding-right: 12px; } }
.cpanel { max-width: 720px; }
/* The night link in the nights table: a 44 px target without growing the row (D2a review). */
table.ctable td a { display: inline-block; padding: 12px 0; margin: -12px 0; }
/* Reports (run 2, D2b, P117 P120): one row to move by week plus one custom range; each night's actions as buttons. */
.weeknav { display: flex; flex-wrap: wrap; gap: 8px; }
.weeknav a { display: inline-flex; align-items: center; gap: 8px; }
.weeknav a[aria-current="true"] { background: var(--gold); color: var(--bg); border-color: var(--gold); }
.rowacts { display: flex; flex-wrap: wrap; gap: 8px; }
.rowacts .btn-line { white-space: nowrap; }
/* A cell's value and its notes as one block, each note on its own line under the value (D2b, phone cards). */
.cv { display: inline-block; }
.cv .note { display: block; font-size: 12.5px; color: var(--muted); }
.cv a.note { color: var(--gold); }
.score .note { font-family: var(--body); text-transform: none; letter-spacing: 0; }
.weeknav a, .rowacts a { min-height: 44px; }
@media (min-width: 901px) { .nbn td:first-child { white-space: nowrap; } }
.byclub .btn-line { white-space: nowrap; min-height: 44px; }
/* Club settings (run 2, cycle E): one closed line per club; the form opens under it. */
.how-tag { margin-top: 6px; }
.how-tag p { margin: 4px 0 8px; max-width: 720px; }
.clubs { display: flex; flex-direction: column; gap: 10px; max-width: 900px; margin-top: 16px; }
details.club { border: 1px solid var(--line); border-radius: 14px; background: var(--card); }
details.club > summary { list-style: none; cursor: pointer; display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 4px 12px; align-items: center; padding: 14px 16px; min-height: 56px; }
details.club > summary::-webkit-details-marker { display: none; }
details.club[open] > summary { border-bottom: 1px dashed var(--line-soft); }
details.club .cn { font-size: 17px; color: var(--gold); min-width: 0; overflow-wrap: anywhere; }
details.club .ch { font-size: 14px; color: var(--muted); }
details.club .cs { display: inline-flex; align-items: center; gap: 10px; font-size: 14px; color: var(--sand); }
details.club .cs::after { content: ''; width: 7px; height: 7px; border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor; transform: translateY(-2px) rotate(45deg); }
details.club[open] .cs::after { transform: translateY(2px) rotate(-135deg); }
details.club .cs.off { color: var(--dim); }
details.club .cw { grid-column: 1 / -1; font-size: 13.5px; color: var(--warn); }
.cbody { padding: 16px; display: flex; flex-direction: column; gap: 20px; }
.cform { display: flex; flex-direction: column; gap: 16px; }
.cact { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; }
.cact .btn-line, .cact .btn-fill, .clink-make .btn-line { height: auto; min-height: 44px; }
.cform textarea { font-size: 17px; }
.field-warn { margin: 0; font-size: 13.5px; color: var(--warn); }
.switch { display: inline-flex; align-items: center; gap: 10px; min-height: 44px; cursor: pointer; color: var(--sand); font-size: 15px; margin-right: 6px; }
.switch input[type="checkbox"] { -webkit-appearance: none; appearance: none; position: relative; flex: none; width: 46px; height: 28px; margin: 0; border-radius: 14px; background: var(--edge); cursor: pointer; accent-color: var(--gold); transition: background .15s; }
.switch input[type="checkbox"]::before { content: ''; position: absolute; top: 3px; left: 3px; width: 22px; height: 22px; border-radius: 50%; background: var(--ivory); transition: transform .15s; }
.switch input[type="checkbox"]:checked { background: var(--gold); }
.switch input[type="checkbox"]:checked::before { transform: translateX(18px); background: var(--bg); }
.switch input[type="checkbox"]:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }
.switch input[type="checkbox"]:disabled { opacity: .5; cursor: default; }
.clinkbox { border-top: 1px dashed var(--line-soft); padding-top: 16px; display: flex; flex-direction: column; gap: 10px; }
.clinkbox h3 { font-size: 15px; margin: 0; }
.clinks { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.clinks li { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 12px; }
.clinks .lh { color: var(--ivory); }
.clinks .ls { color: var(--muted); font-size: 13.5px; }
.clinks .gone { opacity: .55; }
.clinks .btn-small { min-height: 44px; }
.clinks .fresh { flex-basis: 100%; }
.clinks code { overflow-wrap: anywhere; }
.clink-make { display: flex; flex-wrap: wrap; gap: 10px; align-items: flex-end; }
.clink-make .field { flex: 1 1 220px; }
.add-club { margin-top: 16px; max-width: 900px; }
/* Run 2 (P023): the date's weekday, said under it as the team thinks of nights. */
.field-hint.weekday { color: var(--sand); min-height: 1.4em; }
/* Run 2 (P034 P030): the night page's legend, one line per rule. */
.foot p { margin: 0; } .foot p + p { margin-top: 6px; }
/* Run 2 cycle R: a club tag in its four states, each count at equal weight, and a bar that shows at a glance how much
   is known. Gold tagged, terracotta did not, sand being read, bronze couldn't read, grey not known. */
.stats > div.srow, main.club-link .stats > div.srow, main.print .stats > div.srow { flex: 1 0 100%; padding: 2px 16px 6px; }
.tsplit { display: block; text-align: left; max-width: 620px; margin: 0 auto; }
.tsbar { display: flex; gap: 2px; height: 8px; border-radius: 4px; overflow: hidden; margin-bottom: 10px; }
.tsbar i { display: block; min-width: 6px; }
.tsk { display: flex; flex-wrap: wrap; gap: 6px 18px; font-size: 14px; color: var(--sand); }
.tsk > span { display: inline-flex; align-items: baseline; gap: 6px; }
.tsk i { display: block; width: 9px; height: 9px; border-radius: 2px; align-self: center; }
.tsk b { font-family: var(--display); font-weight: 400; font-size: 20px; color: var(--ivory); }
.tsplit .ts-t { background: var(--gold); } .tsplit .ts-u { background: var(--warn); } .tsplit .ts-r { background: var(--sand); }
.tsplit .ts-s { background: #A07B4C; } .tsplit .ts-k { background: var(--edge); }
.tsbar i, .tsk i { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
.tscap { display: block; margin-top: 8px; }
.tonight .tsplit { grid-column: 1 / -1; max-width: none; margin: 2px 0 0; }
/* On the card the counts keep the card's own number style (tn-stats above), not the big tiles' display type. */
.tonight .tsk b { font-family: inherit; font-weight: 500; font-size: 17px; }
@media print { .tsk { color: #333; } .tsk b { color: #000; } }
