/* ZinoLife365 — "the logbook"
 *
 * Concept: Zinzino's printed workbook, kept honestly for 120 days, ruled and
 * dated, with a blood number at either end. Full plan in DESIGN.md.
 *
 * Three rules this file exists to enforce:
 *   1. Ruled ledger, not a stack of cards. Sections are separated by hairline
 *      rules and space. No universal border-radius, no universal shadow.
 *   2. The numerals are the display face. Tabular mono, tracked, at scale.
 *   3. Gold is spent in exactly one place: the season measure and completed
 *      marks. Everywhere else stays quiet.
 *
 * Accessibility is load-bearing here, not a pass at the end: several of this
 * audience run large text, so everything sizes in rem and nothing is pinned to
 * a fixed height.
 */

:root {
  --ink: #12212F;
  --paper: #F7F3EA;
  --rule: #C3CBD4;
  --gold: #A8842A;
  --sea: #1D4A6B;
  --logged: #2C6B4F;

  --bg: var(--paper);
  --surface: #FDFBF6;
  --text: var(--ink);
  /* Neutrals biased toward the navy so they read chosen, not default grey. */
  --text-soft: #5A6B7C;
  --text-faint: #5E6E7B;   /* 4.75:1 on paper */
  --line: var(--rule);
  --line-soft: #DFE3E4;
  --accent: #7E6315;      /* 5.15:1 on paper */
  --accent-bg: #F2EAD6;

  --wrap: 46rem;
  --gap: 1.35rem;
  --ease: cubic-bezier(.2, .7, .3, 1);
  --spring: linear(0, .38 12%, .78 24%, .98 32%, 1.06 40%, 1.03 52%, 1);

  --mono: ui-monospace, "SF Mono", "Cascadia Code", Menlo, Consolas, monospace;
  --sans: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --prose: Georgia, "Iowan Old Style", "Palatino Linotype", ui-serif, serif;
}

[data-theme="dark"] {
  --bg: #0C1721;
  --surface: #12212F;
  --text: #EDEFE9;
  --text-soft: #9FB0BF;
  --text-faint: #8195A8;   /* 5.29:1 on the dark surface */
  --line: #263B4D;
  --line-soft: #1C2E3D;
  --accent: #D6B45C;
  --accent-bg: #1A2B3A;
  --logged: #64B98F;
  --gold: #D6B45C;
}

* { box-sizing: border-box; }

/* The hidden attribute must win.
   `[hidden]` only sets display:none at user-agent specificity, so any class
   with its own display (.zl-btn is inline-flex, .zl-error is flex) silently
   overrides it and the element stays visible. That is how the passkey button
   ended up showing to people who have no passkey, which is the precise failure
   the whole conditional-UI design exists to prevent. */
[hidden] { display: none !important; }

body.zl {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--sans);
  font-size: 1rem;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  padding-bottom: 5.5rem;
}

.zl-wrap { max-width: var(--wrap); margin: 0 auto; padding: 0 1.15rem; }

/* Every figure in the app aligns on the digit. */
.zl-num {
  font-family: var(--mono);
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
  letter-spacing: .02em;
}

/* ---------- Masthead ---------- */
.zl-header {
  position: sticky; top: 0; z-index: 20;
  background: var(--bg);
  border-bottom: 1px solid var(--line);
}
.zl-header-in {
  max-width: var(--wrap); margin: 0 auto; padding: .7rem 1.15rem;
  display: flex; align-items: center; gap: .6rem;
}
.zl-logo {
  display: inline-flex; align-items: center; min-height: 2.75rem;
  font-family: var(--mono); font-weight: 600; font-size: .95rem;
  letter-spacing: .1em; text-transform: uppercase;
  color: var(--text); text-decoration: none;
}
.zl-logo span { color: var(--accent); }
.zl-header-spacer { flex: 1; }

.zl-iconbtn {
  background: transparent; border: 1px solid var(--line); color: var(--text-soft);
  min-width: 2.75rem; min-height: 2.75rem; padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
  cursor: pointer; transition: color .18s var(--ease), border-color .18s var(--ease);
}
.zl-iconbtn:hover { color: var(--text); border-color: var(--text-soft); }
.zl-iconbtn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.zl-iconbtn svg { width: 1.15rem; height: 1.15rem; }

.zl-backlink {
  display: inline-flex; align-items: center; gap: .35rem;
  min-width: 2.75rem; min-height: 2.75rem; padding: 0 .7rem;
  justify-content: center;
  color: var(--text-soft); text-decoration: none;
  font-size: .78rem; letter-spacing: .08em; text-transform: uppercase;
  border: 1px solid var(--line);
}
.zl-backlink:hover { color: var(--text); border-color: var(--text-soft); }
.zl-backlink:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.zl-backlink svg { width: .9rem; height: .9rem; }
@media (max-width: 26rem) { .zl-backlink-text { display: none; } }

/* ---------- THE SEASON MEASURE (signature device) ----------
   The product's whole idea drawn once: 120 days with a blood number at either
   end, checkpoints ticked along it, filled to today. This replaced a 4px bar. */
.zl-measure { border-bottom: 1px solid var(--line); background: var(--bg); }
.zl-measure-in { max-width: var(--wrap); margin: 0 auto; padding: 1.1rem 1.15rem 1rem; }

.zl-measure-head {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 1rem; margin-bottom: .85rem;
}
.zl-measure-day { line-height: 1; }
.zl-measure-day b {
  display: block; font-family: var(--mono); font-weight: 600;
  font-size: 2.6rem; letter-spacing: -.03em; color: var(--text);
  font-variant-numeric: tabular-nums;
}
.zl-measure-day small {
  display: block; margin-top: .3rem;
  font-size: .7rem; letter-spacing: .14em; text-transform: uppercase;
  color: var(--text-faint);
}
.zl-measure-count {
  text-align: right; font-size: .72rem; letter-spacing: .1em;
  text-transform: uppercase; color: var(--text-faint);
}
.zl-measure-count b {
  display: block; font-family: var(--mono); font-size: 1.05rem;
  font-weight: 600; color: var(--text); letter-spacing: 0;
  font-variant-numeric: tabular-nums;
}

/* The rule itself. 3px so the checkpoint ticks have something to sit on. */
.zl-rule { position: relative; height: 3px; background: var(--line); }
.zl-rule-fill {
  position: absolute; inset: 0 auto 0 0; width: 0;
  background: linear-gradient(90deg, var(--sea), var(--gold));
  transform-origin: left center;
}
.zl-rule-tick {
  position: absolute; top: -4px; width: 1px; height: 11px;
  background: var(--line);
}
.zl-rule-tick[data-passed="1"] { background: var(--gold); }
.zl-rule-today {
  position: absolute; top: -7px; width: 3px; height: 17px;
  background: var(--text); transform: translateX(-1px);
}

.zl-measure-ends {
  display: flex; justify-content: space-between; margin-top: .6rem;
  font-size: .72rem; letter-spacing: .08em; text-transform: uppercase;
  color: var(--text-faint);
}
.zl-measure-ends b {
  font-family: var(--mono); font-size: .95rem; letter-spacing: 0;
  color: var(--text); display: block; text-transform: none;
  font-variant-numeric: tabular-nums;
}
.zl-measure-ends span:last-child { text-align: right; }
/* An unrecorded ratio is pending, not broken: a ruled blank is what a paper
   logbook would show, and it invites the entry instead of looking like an error. */
.zl-measure-ends .zl-pending {
  color: transparent; position: relative; display: inline-block; min-width: 2.6rem;
}
.zl-measure-ends .zl-pending::after {
  content: ""; position: absolute; left: 0; right: .4rem; bottom: .22em;
  border-bottom: 1px solid var(--line);
}

/* ---------- Sheets: ruled sections, not floating cards ---------- */
.zl-card, .zl-sheet {
  background: transparent;
  border: 0;
  border-top: 1px solid var(--line-soft);
  border-radius: 0;
  box-shadow: none;
  padding: var(--gap) 0;
  margin: 0;
}
.zl-wrap > .zl-card:first-of-type,
.zl-wrap > .zl-sheet:first-of-type { border-top: 0; }

.zl-card h2, .zl-sheet h2 {
  margin: 0 0 .15rem;
  font-size: 1.02rem; font-weight: 600; letter-spacing: -.005em;
}
.zl-card h3 { margin: 1.2rem 0 .3rem; font-size: .95rem; font-weight: 600; }
.zl-card p { margin: .45rem 0; }
.zl-muted { color: var(--text-soft); font-size: .92rem; }
.zl-center { text-align: center; }

/* Section eyebrow: small caps label, the ledger's column heading. */
.zl-eyebrow {
  font-size: .68rem; letter-spacing: .16em; text-transform: uppercase;
  color: var(--text-faint); font-weight: 600; display: block;
  margin-bottom: .3rem;
}

/* A panel is used only where something genuinely is a contained object
   (the restart card, an alert). Not the default container. */
.zl-panel {
  border: 1px solid var(--line);
  background: var(--surface);
  padding: 1rem 1.1rem;
  margin: var(--gap) 0;
}
.zl-panel.zl-mark { border-left: 3px solid var(--ink); }
[data-theme="dark"] .zl-panel.zl-mark { border-left-color: var(--text-soft); }

/* ---------- The day's entries ---------- */
.zl-tasks { list-style: none; margin: .7rem 0 0; padding: 0; }
.zl-tasks > li { border-top: 1px solid var(--line-soft); }
.zl-tasks > li:first-child { border-top: 0; }

.zl-task {
  display: flex; align-items: center; gap: .9rem;
  width: 100%; min-height: 3.5rem; padding: .75rem 0;
  background: none; border: 0; border-radius: 0;
  font: inherit; color: inherit; text-align: left; cursor: pointer;
}
.zl-task:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

/* The mark. Hand-drawn tick in a ruled box, the way you would tick a workbook.
   Only this changes on toggle: per Carla's rule we never animate a control the
   member is about to tap, so the row never moves under a finger. */
.zl-mark-box {
  flex: 0 0 auto; width: 1.6rem; height: 1.6rem;
  border: 1.5px solid var(--line); position: relative;
  transition: border-color .2s var(--ease), background-color .2s var(--ease);
}
.zl-mark-box svg {
  position: absolute; inset: 0; width: 100%; height: 100%;
  stroke: var(--gold); stroke-width: 2.4; fill: none;
  stroke-linecap: round; stroke-linejoin: round;
  stroke-dasharray: 22; stroke-dashoffset: 22;
}
.zl-task[aria-pressed="true"] .zl-mark-box { border-color: var(--gold); }
.zl-task[aria-pressed="true"] .zl-mark-box svg {
  stroke-dashoffset: 0;
  transition: stroke-dashoffset .34s var(--spring);
}

.zl-task-body { flex: 1; min-width: 0; }
.zl-task-label { display: block; font-weight: 500; }
.zl-task[aria-pressed="true"] .zl-task-label { color: var(--text-soft); }
.zl-task-detail {
  display: block; font-size: .8rem; color: var(--text-faint);
  font-family: var(--mono); font-variant-numeric: tabular-nums;
}
/* The figure on the right of the ledger line. */
.zl-task-figure {
  flex: 0 0 auto; font-family: var(--mono); font-size: .95rem;
  color: var(--text-faint); font-variant-numeric: tabular-nums;
}
.zl-task[aria-pressed="true"] .zl-task-figure { color: var(--gold); }

.zl-pill {
  display: inline-block; font-size: .62rem; letter-spacing: .12em;
  text-transform: uppercase; font-weight: 600;
  color: var(--text-faint);
}

/* ---------- Zinzino, quoted ----------
   Their words, unedited, with the page they came from set as a marginal note.
   No tinted box, no accent rail: this is a citation, not a callout. */
.zl-quote { margin: 1.15rem 0; padding-left: 1rem; border-left: 1px solid var(--line); }
.zl-quote h4 { margin: 0 0 .35rem; font-size: .95rem; font-weight: 600; }
.zl-quote p { margin: .4rem 0; white-space: pre-line; color: var(--text); }
.zl-quote cite {
  display: block; margin-top: .55rem; font-style: normal;
  font-family: var(--mono); font-size: .68rem; letter-spacing: .06em;
  color: var(--text-faint);
}
.zl-quote.zl-pinned { border-left-color: var(--gold); }

/* ---------- Dr. Carla, writing ----------
   Set as prose, because it is prose. This is what tells a reader they have
   moved from the app's voice to a person's. */
.zl-lesson { margin: 1.4rem 0; }
.zl-lesson h4 {
  margin: 0 0 .3rem; font-family: var(--sans);
  font-size: .68rem; letter-spacing: .16em; text-transform: uppercase;
  color: var(--text-faint); font-weight: 600;
}
.zl-lesson p {
  margin: .55rem 0; white-space: pre-line;
  font-family: var(--prose); font-size: 1.06rem; line-height: 1.72;
}
.zl-lesson.zl-pinned {
  border-top: 1px solid var(--line); border-bottom: 1px solid var(--line);
  padding: .9rem 0;
}
.zl-lesson.zl-pinned p { font-size: .95rem; color: var(--text-soft); }

/* ---------- Buttons ---------- */
.zl-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .5rem;
  min-height: 2.9rem; padding: .7rem 1.2rem;
  border: 1px solid var(--ink); border-radius: 0;
  background: var(--ink); color: var(--paper);
  font: inherit; font-size: .92rem; font-weight: 600; cursor: pointer;
  text-decoration: none;
  transition: opacity .16s var(--ease), transform .16s var(--ease);
}
[data-theme="dark"] .zl-btn { background: var(--text); color: var(--bg); border-color: var(--text); }
.zl-btn:hover { opacity: .88; }
.zl-btn:active { transform: translateY(1px); }
.zl-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.zl-btn-gold { background: var(--gold); border-color: var(--gold); color: #1B1405; }
.zl-btn-ghost { background: transparent; color: var(--text); border-color: var(--line); }
.zl-btn-ghost:hover { border-color: var(--text-soft); }
.zl-btn-block { display: flex; width: 100%; }
.zl-btn[disabled] { opacity: .45; cursor: not-allowed; }

/* ---------- Forms ---------- */
.zl-field { margin: .9rem 0; }
.zl-field label {
  display: block; margin-bottom: .3rem;
  font-size: .7rem; letter-spacing: .12em; text-transform: uppercase;
  font-weight: 600; color: var(--text-faint);
}
.zl-input, .zl-textarea, .zl-select {
  width: 100%; padding: .65rem .1rem; font: inherit;
  color: var(--text); background: transparent;
  border: 0; border-bottom: 1px solid var(--line); border-radius: 0;
}
.zl-select { padding-left: 0; }
.zl-input:focus, .zl-textarea:focus, .zl-select:focus {
  outline: none; border-bottom-color: var(--accent); border-bottom-width: 2px;
}
.zl-input:focus-visible, .zl-textarea:focus-visible, .zl-select:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 3px;
}
.zl-textarea { min-height: 6rem; resize: vertical; font-family: var(--prose); }
/* Errors carry an icon and weight, never colour alone. */
.zl-error {
  display: flex; align-items: flex-start; gap: .4rem;
  color: #A32017; font-size: .88rem; font-weight: 600; margin-top: .45rem;
}
.zl-error::before { content: "!"; font-family: var(--mono); flex: 0 0 auto; }
[data-theme="dark"] .zl-error { color: #F0A9A2; }

/* ---------- Pillar index ---------- */
.zl-pillars { display: grid; grid-template-columns: repeat(2, 1fr); gap: 1px;
  background: var(--line-soft); border-top: 1px solid var(--line-soft);
  border-bottom: 1px solid var(--line-soft); margin-top: .8rem; }
/* An odd last item spans rather than sitting beside an empty cell. */
.zl-pillars > .zl-pillar:last-child:nth-child(odd) { grid-column: 1 / -1; }
.zl-pillars > .zl-pillar:last-child:nth-child(odd) .zl-pillar-img { aspect-ratio: 3 / 1; }
@media (min-width: 40rem) {
  .zl-pillars { grid-template-columns: repeat(3, 1fr); }
  .zl-pillars > .zl-pillar:last-child:nth-child(odd) { grid-column: auto; }
  .zl-pillars > .zl-pillar:last-child:nth-child(odd) .zl-pillar-img { aspect-ratio: 3 / 2; }
}
.zl-pillar {
  display: flex; flex-direction: column; background: var(--bg);
  text-decoration: none; color: inherit; padding: 0;
  transition: background-color .18s var(--ease);
}
.zl-pillar:hover { background: var(--surface); }
.zl-pillar:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.zl-pillar-img { display: block; width: 100%; aspect-ratio: 3 / 2; object-fit: cover; }
.zl-pillar-body { padding: .7rem .8rem .9rem; display: flex; flex-direction: column; gap: .15rem; }
.zl-pillar-name {
  display: flex; align-items: center; gap: .4rem;
  font-size: .68rem; letter-spacing: .14em; text-transform: uppercase;
  font-weight: 600; color: var(--accent);
}
.zl-pillar-name svg { width: .85rem; height: .85rem; flex: 0 0 auto; }
.zl-pillar-blurb { font-size: .85rem; color: var(--text-soft); line-height: 1.45; }

/* ---------- Ledger tables ---------- */
.zl-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; margin: .9rem 0; }
.zl-table { width: 100%; border-collapse: collapse; font-size: .9rem; min-width: 30rem; }
.zl-table th, .zl-table td {
  border: 0; border-bottom: 1px solid var(--line-soft);
  padding: .55rem .7rem .55rem 0; text-align: left;
}
.zl-table th {
  font-size: .66rem; letter-spacing: .13em; text-transform: uppercase;
  color: var(--text-faint); font-weight: 600; border-bottom-color: var(--line);
}
.zl-table td { font-variant-numeric: tabular-nums; }
.zl-table td:not(:first-child) { font-family: var(--mono); }
.zl-table td input {
  width: 100%; border: 0; background: transparent; font: inherit;
  color: inherit; padding: .1rem 0; font-family: var(--mono);
}
.zl-table td input:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* The plan grid and the measures table are spreadsheets: 56 cells cannot each
   be 44px tall on a desktop without the table becoming unusable. So the cells
   stay dense for a mouse and grow to the full touch target on a touch device,
   which is where the 44px floor actually protects someone. */
@media (pointer: coarse) {
  .zl-table td { padding-top: .1rem; padding-bottom: .1rem; }
  .zl-table td input { min-height: 44px; padding: .1rem .3rem; }
}
.zl-table tr.zl-row-today td { color: var(--text); font-weight: 600; }
.zl-table tr.zl-row-today td:first-child { position: relative; }
.zl-table tr.zl-row-today td:first-child::before {
  content: ""; position: absolute; left: -.6rem; top: 50%;
  width: 3px; height: 3px; background: var(--gold); transform: translateY(-50%);
}

/* ---------- Bottom index ---------- */
.zl-nav {
  position: fixed; bottom: 0; left: 0; right: 0; z-index: 30;
  background: var(--bg); border-top: 1px solid var(--line);
  padding-bottom: env(safe-area-inset-bottom);
}
.zl-nav-in { max-width: var(--wrap); margin: 0 auto; display: flex; }
.zl-nav a {
  flex: 1; min-height: 3.4rem; padding: .5rem .2rem;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: .25rem; text-decoration: none; color: var(--text-faint);
  font-size: .6rem; letter-spacing: .09em; text-transform: uppercase; font-weight: 600;
}
.zl-nav a svg { width: 1.15rem; height: 1.15rem; }
.zl-nav a[aria-current="page"] { color: var(--text); }
.zl-nav a[aria-current="page"] svg { color: var(--gold); }
.zl-nav a:focus-visible { outline: 2px solid var(--accent); outline-offset: -3px; }

/* ---------- Roster ---------- */
.zl-roster { list-style: none; margin: .5rem 0 0; padding: 0; }
.zl-roster li {
  display: flex; align-items: center; gap: .8rem;
  padding: .85rem 0; border-top: 1px solid var(--line-soft);
}
.zl-roster li:first-child { border-top: 0; }
.zl-dot { width: .5rem; height: .5rem; background: var(--line); flex: 0 0 auto; }
.zl-dot.on { background: var(--logged); }
.zl-dot.quiet { background: var(--gold); }
.zl-roster-name { font-weight: 600; }
.zl-roster-meta {
  font-size: .8rem; color: var(--text-faint);
  font-family: var(--mono); font-variant-numeric: tabular-nums;
}

/* ---------- Restart ---------- */
.zl-restart { border-left: 3px solid var(--gold); }
.zl-why {
  font-family: var(--prose); font-size: 1.08rem; line-height: 1.7;
  padding-left: 1rem; border-left: 1px solid var(--line);
  margin: .8rem 0; white-space: pre-line;
}

/* A link inside muted copy carries an underline as well as a colour, and gets
   hit-slop so the tap target clears 44px without changing the text size. */
.zl-muted a, .zl-task-detail a {
  color: var(--text); text-decoration: underline; text-underline-offset: .18em;
  display: inline-block; padding: .7rem 0;
}
.zl-muted a:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ---------- Empty states ---------- */
.zl-empty { padding: 1.5rem 0; text-align: center; }
.zl-empty svg { width: 2rem; height: 2rem; color: var(--text-faint); margin-bottom: .6rem; }
.zl-empty p { margin: 0 0 .9rem; color: var(--text-soft); font-size: .92rem; }

/* ---------- Nudge ---------- */
.zl-nudge { border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); background: var(--accent-bg); }
.zl-nudge .zl-wrap { display: flex; align-items: center; gap: .9rem; flex-wrap: wrap; padding-top: .85rem; padding-bottom: .85rem; }
.zl-nudge p { margin: 0; flex: 1 1 14rem; font-size: .9rem; }

/* ---------- Account choice ---------- */
.zl-choice { border: 0; margin: 0 0 1rem; padding: 0; }
.zl-choice legend { font-size: .7rem; letter-spacing: .12em; text-transform: uppercase; font-weight: 600; color: var(--text-faint); margin-bottom: .5rem; padding: 0; }
.zl-choice-opt {
  display: flex; align-items: flex-start; gap: .7rem;
  padding: .85rem 0; border-top: 1px solid var(--line-soft); cursor: pointer;
}
.zl-choice-opt:has(input:checked) { border-top-color: var(--gold); }
.zl-choice-opt:focus-within { outline: 2px solid var(--accent); outline-offset: 3px; }
/* The label is the real 44px+ target and wraps this control; the input is
   still enlarged so it is comfortable to hit directly. */
.zl-choice-opt input { margin-top: .3rem; flex: 0 0 auto; accent-color: var(--gold); width: 1.35rem; height: 1.35rem; }
.zl-choice-opt span { display: flex; flex-direction: column; gap: .1rem; }
.zl-choice-opt small { color: var(--text-soft); font-size: .85rem; }

/* ---------- Hero / banner ---------- */
.zl-hero { position: relative; margin: 0 -1.15rem; background: var(--ink); }
.zl-hero img { display: block; width: 100%; height: auto; aspect-ratio: 16 / 9; object-fit: cover; }
.zl-hero-copy {
  position: absolute; inset: auto 0 0 0; padding: 2rem 1.15rem 1.15rem;
  background: linear-gradient(to top, rgba(9, 20, 30, .94) 15%, rgba(9, 20, 30, .5) 60%, transparent);
  color: #fff;
}
.zl-hero-copy .zl-eyebrow { color: var(--gold); }
.zl-hero-copy h2 { margin: .2rem 0 0; font-size: 1.5rem; line-height: 1.2; letter-spacing: -.02em; text-wrap: balance; }

.zl-banner { position: relative; margin: 0 -1.15rem 0; background: var(--ink); }
.zl-banner img { display: block; width: 100%; height: auto; aspect-ratio: 2 / 1; object-fit: cover; }
.zl-banner-copy {
  position: absolute; inset: auto 0 0 0; padding: 2rem 1.15rem 1rem;
  background: linear-gradient(to top, rgba(9, 20, 30, .92) 12%, rgba(9, 20, 30, .45) 62%, transparent);
  color: #fff;
}
.zl-banner-copy .zl-eyebrow { color: var(--gold); }
.zl-banner-copy h2 { margin: .15rem 0 0; font-size: 1.15rem; color: #fff; }
.zl-banner-copy p { margin: .25rem 0 0; color: #C9D5DF; font-size: .85rem; }

/* ---------- Attribution ---------- */
.zl-attrib { margin-top: 2.5rem; padding: 1.3rem 0 1.6rem; border-top: 1px solid var(--line); }
.zl-attrib p { margin: .3rem 0; font-size: .72rem; line-height: 1.55; color: var(--text-faint); text-align: center; }

/* ---------- Toast / offline / modal ---------- */
.zl-toast {
  position: fixed; left: 50%; bottom: 5.4rem; transform: translate(-50%, .8rem);
  background: var(--ink); color: var(--paper); padding: .6rem 1.1rem;
  font-size: .85rem; opacity: 0; pointer-events: none; z-index: 60;
  transition: opacity .2s var(--ease), transform .2s var(--ease);
}
.zl-toast.show { opacity: 1; transform: translate(-50%, 0); }

.zl-offline {
  display: none; background: var(--gold); color: #1B1405;
  text-align: center; padding: .4rem; font-size: .82rem; font-weight: 600;
}
body.zl-is-offline .zl-offline { display: block; }

.zl-modal {
  border: 1px solid var(--line); padding: 0; border-radius: 0;
  background: var(--surface); color: var(--text);
  max-width: 26rem; width: calc(100% - 2rem);
}
.zl-modal::backdrop { background: rgba(9, 20, 30, .6); }
.zl-modal-in { padding: 1.2rem; }
.zl-modal h3 { margin: 0 0 .5rem; }
.zl-modal-actions { display: flex; gap: .6rem; justify-content: flex-end; margin-top: 1.1rem; }

/* Reduced motion: movement goes, colour stays. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important; animation-iteration-count: 1 !important;
    transition-duration: .01ms !important; scroll-behavior: auto !important;
  }
}

/* ---------- The gate (zinolife365.com front door) ----------
   Almost empty on purpose. Somebody here wants to get in, so the page is a
   wordmark, two tabs and the fields. The explaining lives on /join. */
.zl-gate { max-width: 22rem; margin: 2.5rem auto 0; }
.zl-gate-mark {
  font-family: var(--mono); font-weight: 600; font-size: 1.15rem;
  letter-spacing: .12em; text-align: center; margin-bottom: 2rem;
}
.zl-gate-mark span { color: var(--accent); }

.zl-tabs { display: flex; border-bottom: 1px solid var(--line); margin-bottom: 1.4rem; }
.zl-tab {
  flex: 1; min-height: 2.9rem; padding: .7rem .5rem;
  background: none; border: 0; border-bottom: 2px solid transparent;
  font: inherit; font-size: .72rem; font-weight: 600;
  letter-spacing: .14em; text-transform: uppercase;
  color: var(--text-faint); cursor: pointer; margin-bottom: -1px;
}
.zl-tab[aria-selected="true"] { color: var(--text); border-bottom-color: var(--gold); }
.zl-tab:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

.zl-gate-alt { text-align: center; margin: 1.1rem 0 0; font-size: .88rem; }
.zl-gate-alt a { color: var(--text); text-decoration: underline; text-underline-offset: .18em;
  display: inline-block; padding: .6rem .2rem; }
.zl-gate-partner {
  margin: 2.2rem 0 0; padding-top: 1.1rem; border-top: 1px solid var(--line-soft);
  font-size: .82rem; color: var(--text-faint); text-align: center;
}

/* ---------- Landing: the idea, drawn ---------- */
.zl-joinmeasure {
  display: flex; align-items: flex-end; gap: .8rem; margin: 1.4rem 0 1rem;
}
.zl-jm-end { flex: 0 0 auto; }
.zl-jm-end b { display: block; font-size: 1.6rem; font-weight: 600; line-height: 1; }
.zl-jm-end small {
  display: block; margin-top: .3rem; font-size: .64rem;
  letter-spacing: .12em; text-transform: uppercase; color: var(--text-faint);
}
.zl-jm-right { text-align: right; }
.zl-jm-rule { flex: 1; position: relative; padding-bottom: .55rem; }
.zl-jm-rule i {
  display: block; height: 3px;
  background: linear-gradient(90deg, var(--sea), var(--gold));
}
.zl-jm-days {
  position: absolute; left: 50%; top: -1.15rem; transform: translateX(-50%);
  font-size: .78rem; color: var(--text-faint);
}

/* ---------- Landing: three true numbers ---------- */
.zl-facts { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1px;
  background: var(--line-soft); border-top: 1px solid var(--line-soft);
  border-bottom: 1px solid var(--line-soft); margin-top: .8rem; }
.zl-fact { background: var(--bg); padding: 1rem .6rem; text-align: center; }
.zl-fact b { display: block; font-family: var(--mono); font-size: 1.5rem;
  font-weight: 600; letter-spacing: -.02em; }
.zl-fact span { display: block; margin-top: .3rem; font-size: .72rem;
  color: var(--text-soft); line-height: 1.35; }

/* ---------- Landing: both doors, at the top ----------
   A visitor who already knows what this is should not have to read the page to
   reach the form, and a returning customer should not have to hunt for sign in. */
.zl-jump {
  display: flex; gap: .6rem; margin: var(--gap) 0 0;
  padding-bottom: var(--gap); border-bottom: 1px solid var(--line-soft);
}
.zl-jump .zl-btn { flex: 1; }

/* ---------- Day zero ----------
   The empty logbook with 120 days ahead of it. This is the first thing a new
   customer sees, so it shows what they signed up for rather than describing it. */
.zl-daynought {
  margin: 0 -1.15rem; padding: 2.2rem 1.15rem 1.6rem;
  background: var(--ink); color: #F7F3EA;
}
[data-theme="dark"] .zl-daynought { background: #08131C; }
.zl-dn-num {
  display: block; font-size: 4rem; font-weight: 600; line-height: .9;
  letter-spacing: -.04em; color: rgba(247,243,234,.22);
}
.zl-dn-rule { height: 3px; background: rgba(247,243,234,.18); margin: 1.1rem 0 .5rem; }
.zl-dn-rule i {
  display: block; width: 3px; height: 100%; background: var(--gold);
}
.zl-dn-ends {
  display: flex; justify-content: space-between;
  font-size: .64rem; letter-spacing: .13em; text-transform: uppercase;
  color: rgba(247,243,234,.5);
}
.zl-daynought h2 {
  margin: 1.5rem 0 .4rem; font-size: 1.4rem; letter-spacing: -.02em;
  color: #F7F3EA; text-wrap: balance;
}
.zl-daynought p { margin: 0; color: #B9C6D2; font-size: .95rem; }

/* ---------- The strip: what your days look like ---------- */
.zl-strip {
  display: flex; gap: 1px; overflow-x: auto; margin: .8rem -1.15rem 0;
  padding: 0 1.15rem; -webkit-overflow-scrolling: touch; scrollbar-width: none;
}
.zl-strip::-webkit-scrollbar { display: none; }
.zl-strip-item { flex: 0 0 7.5rem; margin: 0; }
.zl-strip-item img { display: block; width: 100%; height: 9.5rem; object-fit: cover; }
.zl-strip-item figcaption {
  display: flex; align-items: center; gap: .3rem; padding: .5rem .1rem 0;
  font-size: .63rem; letter-spacing: .12em; text-transform: uppercase;
  font-weight: 600; color: var(--accent);
}
.zl-strip-item figcaption svg { width: .8rem; height: .8rem; flex: 0 0 auto; }

/* ---------- Steps ---------- */
.zl-step .zl-eyebrow { color: var(--accent); }

/* Progressive disclosure: the full lesson is one tap away rather than in the
   way. The wall of prose was the wrong welcome even though the prose is good. */
.zl-more { margin-top: .9rem; }
.zl-more summary {
  cursor: pointer; list-style: none; display: inline-flex; align-items: center;
  gap: .4rem; min-height: 2.75rem; font-size: .78rem; font-weight: 600;
  letter-spacing: .08em; text-transform: uppercase; color: var(--text-faint);
}
.zl-more summary::-webkit-details-marker { display: none; }
.zl-more summary::after { content: "+"; font-family: var(--mono); font-size: 1rem; }
.zl-more[open] summary::after { content: "\2212"; }
.zl-more summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.zl-more[open] summary { color: var(--text); }
