/* Page styles on the Nightcrawler design system (WIP-94). Every colour, font, spacing and
   radius comes from tokens.css; no literal colour here (tests/test_design_tokens.py). */
* { box-sizing: border-box; }
body {
  margin: 0 auto;
  max-width: 720px;
  padding: 0 var(--space-6) 48px;
  background: var(--ground);
  color: var(--ink);
  font: 400 15px/1.45 var(--font-body);
  font-optical-sizing: auto;
}
:focus-visible { outline: 3px solid var(--ink); outline-offset: 2px; }
/* --- home screen (WIP-95): artboard PisteB of the canvas, components of the design system --- */
body { padding-bottom: calc(96px + env(safe-area-inset-bottom)); } /* room for the tab bar */
html { scroll-padding-bottom: calc(96px + env(safe-area-inset-bottom)); } /* focus never under the bar */
header.top { padding: var(--space-6) 0 6px; }
.wordmark { margin: 0; font: 800 28px/1 var(--font-display); letter-spacing: -0.02em; }
.wordmark .dot { color: var(--accent); } /* decoration: the name is read as text */
.meta { margin: 2px 0 0; font-size: 13px; line-height: 1.4; color: var(--ink-muted); }
.muted { color: var(--ink-muted); }
h2 { margin: var(--space-7) 0 var(--space-1); font: 800 26px/1.15 var(--font-display); letter-spacing: -0.01em; }
h2:focus { outline: none; }
h2:focus-visible { outline: 3px solid var(--ink); }

/* ViewTabs */
.views { display: flex; flex-wrap: wrap; gap: 6px; padding-top: var(--space-3); }
.views button {
  font: 400 15px/1.3 var(--font-body); min-height: 40px; padding: 0 16px; border: 0; border-radius: 20px;
  background: var(--surface); color: var(--ink); cursor: pointer; display: inline-flex; align-items: center; gap: 6px;
}
.views button[aria-current] { background: var(--ink); color: var(--on-ink); font-weight: 600; }
.views .count { font-size: 13px; color: var(--ink-muted); }
.views button[aria-current] .count { color: var(--on-ink); }
/* Period chips (WIP-108): one row that scrolls sideways when the four do not fit (320–375px).
   The row bleeds into the page gutter so a cut-off chip at the screen edge shows there is more;
   its padding keeps the 3px focus ring (offset 2px) inside the scroll box, which clips. */
.periods {
  display: flex; flex-wrap: nowrap; column-gap: 18px; overflow-x: auto; scrollbar-width: none;
  margin: 0 calc(-1 * var(--space-6)); padding: var(--space-2) var(--space-6);
  scroll-padding-inline: var(--space-6); /* a chip reached by Tab is scrolled fully into view */
}
.periods::-webkit-scrollbar { display: none; }
.periods button {
  flex: none; white-space: nowrap;
  font: 400 15px/1.3 var(--font-body); min-height: var(--touch-target); padding: 0; border: 0; background: none;
  color: var(--ink-muted); cursor: pointer; border-bottom: 3px solid transparent;
}
.periods button[aria-pressed="true"] { color: var(--ink); font-weight: 700; border-bottom-color: var(--accent); }

/* sections */
.empty { margin: var(--space-6) 0; }
ul.rows { list-style: none; margin: 0; padding: 0; }

/* ConcertRow */
li.crow {
  display: grid; grid-template-columns: 48px minmax(0, 1fr); gap: var(--space-4);
  padding: var(--space-4) 0 6px; border-bottom: 1px solid var(--line);
}
.date { display: flex; flex-direction: column; align-items: center; padding-top: 2px; }
.date .wd { font-size: 11px; font-weight: 700; line-height: 1.3; letter-spacing: 0.04em; color: var(--accent-ink); }
.date .num { font: 800 26px/1 var(--font-display); }
.date .hour { font-size: 11px; color: var(--ink-muted); font-variant-numeric: tabular-nums; }
.body { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.head { display: flex; gap: var(--space-2); align-items: flex-start; justify-content: space-between; }
h3.row-title { margin: 0; font: 600 19px/1.15 var(--font-display); min-width: 0; }
.crow .venue { margin: 0; font-size: 14px; color: var(--ink-muted); overflow-wrap: anywhere; }
.new {
  flex: none; font-size: 12px; font-weight: 700; line-height: 1.45; border-radius: var(--radius-md);
  padding: 2px 8px; background: var(--accent); color: var(--ink);
}

/* Affinity scale (WIP-112). The apricot means « a concert I am most likely to enjoy » (PM,
   2026-10-09), so its strength follows the judge's own ordered score and never the row's
   position: level 3 the full apricot card, level 2 a 30% wash, level 1 a rule alone, level 0
   nothing. The rule is accent-ink, not accent: the accent on white is 1.8:1, under the 3:1 a
   UI element carrying meaning needs. Each level also says its name (.lvl), so the scale is
   never carried by colour alone. The rule is drawn in the page gutter so titles of every level
   stay on the same left edge. */
li.crow.lv1, li.crow.lv2 {
  margin-left: calc(-1 * var(--space-3)); padding-left: calc(var(--space-3) - 3px);
  border-left: 3px solid var(--accent-ink);
}
li.crow.lv2 {
  background: var(--accent-soft); border-left-width: 4px; padding-left: calc(var(--space-3) - 4px);
  margin-right: calc(-1 * var(--space-3)); padding-right: var(--space-3);
  margin-top: var(--space-2); border-bottom-color: transparent;
  border-radius: 0 var(--radius-md) var(--radius-md) 0;
}
.crow.lv2 .new { background: var(--ink); color: var(--on-ink); } /* the accent is invisible on the wash (1.5:1) */
.lvl {
  margin: 0; font-size: 11px; font-weight: 700; line-height: 1.3; letter-spacing: 0.04em;
  text-transform: uppercase; color: var(--accent-ink);
}
.card .lvl { color: var(--ink); } /* accent-ink on the accent is 3.4:1: too low for text */
/* title = disclosure button (details until the concert page, WIP-96): looks like the title */
.title-btn {
  font: inherit; letter-spacing: inherit; color: inherit; text-align: left; background: none; border: 0;
  padding: 0; margin: 0; cursor: pointer; overflow-wrap: anywhere; min-height: 24px;
}
.title-btn:hover { text-decoration: underline; text-decoration-thickness: 2px; }
.title-btn svg { display: inline-block; margin-left: 4px; vertical-align: middle; color: var(--ink-muted); transition: transform 0.15s; }
.title-btn[aria-expanded="true"] svg { transform: rotate(180deg); }
@media (prefers-reduced-motion: reduce) { .title-btn svg { transition: none; } }
.ai-read { white-space: nowrap; }

/* MustSeeCard (WIP-106, the PM's screenshot): apricot card, every text in ink (9.9:1) */
li.card {
  background: var(--accent); color: var(--ink); border-radius: var(--radius-lg); padding: var(--space-5);
  display: flex; flex-direction: column; gap: var(--space-2); min-width: 0; margin: var(--space-3) 0;
}
.card-top { display: flex; justify-content: space-between; align-items: center; gap: var(--space-2); }
.card .when { font-size: 13px; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; }
.card .new { background: var(--ink); color: var(--on-ink); padding: 3px 8px; }
h3.card-title { margin: 0; font: 800 30px/1.02 var(--font-display); letter-spacing: -0.02em; }
.card .sum { position: relative; display: flex; flex-direction: column; gap: var(--space-2); }
.card .title-btn::after { content: ""; position: absolute; inset: -4px; border-radius: 8px; } /* whole text opens the details */
.card .title-btn:focus-visible { outline: none; }
.card .title-btn:focus-visible::after { outline: 3px solid var(--ink); }
.card .sum:hover .title-btn { text-decoration: underline; text-decoration-thickness: 3px; }
.card .venue { margin: 0; font-size: 14px; font-weight: 500; color: var(--ink); overflow-wrap: anywhere; }
.card .reason, .card .muted { color: var(--ink); }
.card .actions { margin-top: 6px; gap: var(--space-1); }
.card button.icon { border-radius: var(--radius-pill); background: var(--veil); color: var(--ink); }
.card .more button.ghost { background: var(--veil); } /* light buttons on the card all sit on the veil */
.card .links a, .card .more { color: var(--ink); }
.card :focus-visible { outline-color: var(--ink); }
button.listen.filled {
  padding: 0 18px 0 14px; border-radius: var(--radius-pill); background: var(--ink); color: var(--on-ink); gap: var(--space-2);
}
.card button.listen.filled:focus-visible { outline-offset: 3px; }
li.card.target { outline: 3px solid var(--ink); outline-offset: 2px; }

/* ReasonTag + sentence: never truncated */
.reason {
  margin: var(--space-1) 0 0; display: flex; gap: var(--space-2); align-items: baseline;
  font-size: 14px; line-height: 1.45; color: var(--ink-soft); overflow-wrap: anywhere;
}
.reason > span:last-child { min-width: 0; }
.reason.muted { color: var(--ink-muted); }
.tag {
  flex: none; font-size: 11px; font-weight: 700; line-height: 1.3; letter-spacing: 0.04em;
  padding: 1px 6px; border-radius: var(--radius-sm); background: var(--ink); color: var(--on-ink);
}

/* actions: ListenButton, like, share */
.actions { display: flex; align-items: center; }
.crow .actions { margin-left: -10px; }
.actions .sp { flex: 1; }
button.icon {
  width: var(--touch-target); height: var(--touch-target); border: 0; padding: 0; background: transparent;
  color: var(--ink-muted); display: inline-flex; align-items: center; justify-content: center; cursor: pointer;
  border-radius: var(--radius-pill);
}
button.icon.on svg { fill: currentColor; }
.crow button.icon.on { color: var(--ink); }
button.listen {
  height: var(--touch-target); padding: 0 10px; border: 0; background: transparent; color: var(--accent-ink);
  font: 700 14px/1 var(--font-body); display: inline-flex; align-items: center; gap: 6px; cursor: pointer;
}
.more { padding: var(--space-1) 0; font-size: 14px; }
.more[hidden] { display: none; }
.links { display: flex; flex-wrap: wrap; align-items: center; column-gap: var(--space-4); margin: 0; }
.more .links a { display: inline-flex; align-items: center; min-height: var(--touch-target); }
button.see-all {
  width: 100%; margin-top: 18px; min-height: 48px; border: 0; border-radius: 24px; background: var(--surface);
  color: var(--ink); font: 700 15px/1 var(--font-body); display: flex; justify-content: center; align-items: center;
  gap: var(--space-2); cursor: pointer;
}
.hint { padding: 10px 12px; border-radius: 8px; background: var(--surface); }

/* Calendrier (WIP-97, artboard Calendrier) */
.screen-title { margin: var(--space-6) 0 var(--space-3); font: 800 28px/1.1 var(--font-display); letter-spacing: -0.02em; }
.cal-head { display: flex; justify-content: space-between; align-items: center; }
.cal-month { font: 600 20px/1.2 var(--font-display); }
button.icon.round { background: var(--surface); color: var(--ink); }
button.icon.round[aria-disabled="true"] { opacity: 0.4; cursor: default; }
.cal { padding-top: var(--space-3); margin: 0 -6px; } /* 14px side gutter, as on the artboard */
.cal-week, .cal-grid { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); text-align: center; }
.cal-week { font-size: 12px; font-weight: 700; color: var(--ink-muted); padding-bottom: 6px; }
.cal-grid { row-gap: var(--space-1); }
.cal-cell { display: flex; flex-direction: column; align-items: center; gap: 3px; min-height: 58px; }
.cal-day {
  width: min(var(--touch-target), 100%); height: var(--touch-target); border-radius: var(--radius-pill);
  border: 2px solid transparent; background: transparent; color: var(--ink); font: 500 16px/1 var(--font-body); cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
}
.cal-day.today { border-color: var(--ink); font-weight: 700; } /* a border survives forced colours */
.cal-day[aria-pressed="true"] { background: var(--ink); border-color: var(--ink); color: var(--on-ink); font-weight: 700; }
.cal-day.past { color: var(--ink-muted); cursor: default; }
/* markers: told apart by shape (WIP-97) */
.mark { display: inline-block; height: 8px; }
.mark.lv3 { width: 14px; border-radius: 4px; background: var(--accent); outline: 1px solid var(--ink); }
/* dot and ring drawn with borders, which forced-colours mode keeps */
.mark.lv2 { width: 8px; height: 8px; box-sizing: border-box; border-radius: 50%; border: 4px solid var(--ink); } /* even width: no hole */
.mark.lv1 { width: 7px; height: 7px; box-sizing: border-box; border-radius: 50%; border: 1.5px solid var(--ink); }
.legend { display: flex; flex-wrap: wrap; gap: var(--space-4); padding: 10px 6px 0; font-size: 13px; color: var(--ink-muted); }
.legend > span { display: inline-flex; align-items: center; gap: 6px; }
.legend > span[hidden] { display: none; }
h3.cal-day-title { margin: 22px 0 var(--space-1); font: 800 22px/1.2 var(--font-display); }
.date.time-only { padding-top: 3px; }
.date .clock { font: 800 18px/1 var(--font-display); font-variant-numeric: tabular-nums; }
button.more-day {
  width: 100%; min-height: 52px; border: 0; background: none; padding: 0; color: var(--accent-ink);
  font: 600 15px/1.3 var(--font-body); display: flex; justify-content: space-between; align-items: center; cursor: pointer;
}

/* bottom navigation */
nav.tabbar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 5; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  max-width: 720px; margin: 0 auto; padding: 6px 0 calc(12px + env(safe-area-inset-bottom));
  background: var(--ground); border-top: 1px solid var(--line);
}
nav.tabbar a {
  display: flex; flex-direction: column; align-items: center; gap: var(--space-1); padding: var(--space-2) 0;
  min-height: var(--touch-target); font-size: 12px; text-decoration: none; color: var(--ink-muted);
}
nav.tabbar a[aria-current] { color: var(--ink); font-weight: 700; }
nav.tabbar a[aria-current] svg { color: var(--accent-ink); stroke-width: 2.2; }

a { color: var(--accent-ink); }
table { width: 100%; border-collapse: collapse; font-size: 14px; }
th, td { text-align: left; padding: 6px 4px; border-bottom: 1px solid var(--line); vertical-align: top; overflow-wrap: anywhere; }
table { table-layout: fixed; }
td:last-child, th:last-child { text-align: right; }
td.fetch_error, td.robots_blocked { font-weight: 700; }
footer { margin-top: 40px; font-size: 13px; color: var(--ink-muted); }

/* --- personalisation (WIP-25) --- */
.visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
textarea, input, select {
  font: inherit; color: var(--ink); background: var(--ground);
  border: 1px solid var(--ink-muted); border-radius: 8px; padding: 6px 8px; min-height: var(--touch-target);
}
textarea { width: 100%; resize: vertical; }
.row { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); margin: var(--space-2) 0; }
.row input { flex: 1 1 140px; min-width: 0; }
/* owner / visitor blocks (ADR-0008): hidden must win over .row's flex */
.row[hidden], [data-owner][hidden], [data-visitor][hidden] { display: none; }
.toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); margin: var(--space-3) 0 var(--space-1); }
.toolbar select { max-width: 100%; }
.toolbar[hidden] { display: none; }
button.primary, button.ghost {
  font: inherit; font-size: 14px; font-weight: 700; cursor: pointer; border-radius: var(--radius-pill);
  min-height: var(--touch-target); padding: 0 14px;
}
button.primary { background: var(--ink); color: var(--on-ink); border: 0; }
button.ghost { background: var(--surface); color: var(--ink); border: 0; }
button.ghost.on { background: var(--ink); color: var(--on-ink); }
.why { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; font-size: 14px; color: var(--ink-soft); }
.badge {
  font-size: 11px; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase;
  padding: 1px 6px; border-radius: var(--radius-sm); background: var(--ink); color: var(--on-ink);
}
iframe.player { width: 100%; height: 300px; border: 0; margin-top: var(--space-2); border-radius: 8px; }

/* --- shared link to a concert (WIP-29) --- */
li.crow.target {
  margin: 0 -10px; padding: var(--space-4) 10px 6px; border-radius: 10px;
  background: color-mix(in srgb, var(--accent) 30%, var(--ground)); outline: none;
}

/* "Mauvais rapprochement": a quiet text button next to the reason (WIP-41) */
button.linkish {
  background: none; border: 0; padding: 0 0 0 0.5em; font: inherit; font-size: 0.85em;
  color: var(--ink-muted); text-decoration: underline; cursor: pointer; min-height: 24px;
}

/* visible errors and Spotify news (WIP-47): errors in ink, news on surface */
.banner {
  position: sticky; top: 0; z-index: 10;
  display: flex; gap: var(--space-2); align-items: baseline; justify-content: space-between;
  margin: var(--space-2) 0 0; padding: 10px 12px; border-radius: 10px;
  background: var(--ink); color: var(--on-ink);
}
.banner .linkish { color: inherit; }
.banner :focus-visible { outline-color: var(--on-ink); } /* ink ring on ink is 1:1 (WCAG 2.4.7) */
.banner.info { background: var(--surface); color: var(--ink); }
.banner.info .linkish { color: var(--ink-muted); }
.banner.info :focus-visible { outline-color: var(--ink); }
.banner.inline { position: static; margin: 0 0 var(--space-2); } /* pending ratings (WIP-70) */
.banner[hidden] { display: none; }

/* "Mon goût en mots" and "À trier" (WIP-73) */
.field-label { display: block; margin: 14px 0 var(--space-1); font-weight: 600; }
.small { font-size: 13px; margin: var(--space-1) 0; }
dialog.sorter {
  width: min(560px, calc(100vw - 32px)); max-height: calc(100dvh - 32px); overflow: auto;
  padding: var(--space-4); border: 1px solid var(--line); border-radius: var(--radius-lg);
  background: var(--ground); color: var(--ink);
}
dialog.sorter::backdrop { background: color-mix(in srgb, var(--ink) 45%, transparent); }
.sorter-head { display: flex; justify-content: space-between; align-items: center; gap: var(--space-2); }
.sorter-head h2 { margin: 0; }
.sorter-card { margin: var(--space-3) 0; min-height: 8rem; }
.sorter-card p { margin: var(--space-1) 0; }
.sorter-title { margin: 0 0 6px; font: 800 24px/1.1 var(--font-display); overflow-wrap: anywhere; outline: none; }
.sorter-when { font-weight: 600; }
.sorter-actions { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-2); }
.sorter-actions[hidden] { display: none; }
button.big {
  font: inherit; font-weight: 700; cursor: pointer; min-height: 56px; padding: var(--space-2);
  border-radius: var(--radius-lg); border: 0; background: var(--surface); color: var(--ink);
}
button.big.primary { background: var(--ink); color: var(--on-ink); }
/* touch screens: no keyboard, no shortcut hint */
@media (hover: none) and (pointer: coarse) { .sorter-keys { display: none; } }
