/* site/app/screens/news.css — the noticeboard.
 * Depends on tokens.css + ui.css + shell.css. Every colour, size, easing and duration comes
 * from a token; a hex written here would not follow the palette into dark mode.
 *
 * ⚠ EVERY CLASS IS PREFIXED nw-. Six screens load their CSS into one document, so an
 *   unprefixed .row or .card here would silently restyle another tab's list. The shared
 *   vocabulary (.sec, .empty, .price, .enter, .mono-nums) is used as-is and never redefined.
 *
 * This is the most EDITORIAL screen in the app, so Fraunces does more work here than
 * anywhere else — the pinned headline, every announcement headline, and the day numbers in
 * the week strip. The serif is what makes a noticeboard read as written rather than
 * generated, and it is the whole reason this tab does not feel like a feed.
 */

/* ═══ 1 · THE PINNED NOTICE ════════════════════════════════════════════════
 * ⚠ DISTINCT BY INVERSION. Navy card on the cream page; cream card on the navy page. A
 *   card that is navy in both themes disappears in dark mode, because the page behind it
 *   is already navy — that is the bug this pattern exists to avoid, and it is invisible to
 *   anyone reviewing in light mode only.
 */
.nw-pin {
  background: var(--navy);
  color: var(--cream);
  margin: 0 16px 22px;
  padding: 18px 18px 16px;
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-2);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .nw-pin { background: var(--cream); color: var(--navy); }
}
:root[data-theme="dark"] .nw-pin { background: var(--cream); color: var(--navy); }

/* Secondary ink inside the pin is derived from currentColor rather than a token, because
   the token for "dimmed ink" is wrong here by definition: the card's ground is inverted
   relative to the page, so the page's ink tokens are the ground colour, not the text. */
.nw-pin-kick {
  display: flex; align-items: center; gap: 6px;
  margin: 0 0 10px;
  font: 600 11px/1 var(--font-ui); letter-spacing: .09em; text-transform: uppercase;
  color: color-mix(in srgb, currentColor 66%, transparent);
}
.nw-pin-ico svg { width: 14px; height: 14px; display: block; }

.nw-pin-head {
  font-family: var(--font-display); font-weight: 600;
  font-size: 23px; line-height: 1.16; letter-spacing: -.014em;
  margin: 0; color: inherit; text-wrap: balance;
}
.nw-pin-body {
  margin: 9px 0 0;
  font: 400 15px/1.5 var(--font-ui);
  color: color-mix(in srgb, currentColor 82%, transparent);
}
.nw-pin-foot {
  margin: 13px 0 0;
  font: 500 12px/1 var(--font-ui); letter-spacing: .02em;
  font-variant-numeric: tabular-nums;
  /* ⚠ 64%, NOT 58% — AND THE TWO THEMES ARE NOT SYMMETRIC. Deriving the dim inks from
     currentColor is right (the card's ground is inverted, so the page's ink tokens are the
     ground here), but the same percentage does NOT buy the same contrast in both directions:
     cream dimmed over navy stays far from its ground, navy dimmed over cream collapses
     toward it. At 58% this measured 8.9 in light and 4.14 in dark — passing in the theme
     everyone reviews in and failing in the other. 64% measures 5.02 dark / 8.2 light, and is
     still dimmer than .nw-pin-kick above it (5.34) so the hierarchy on the card is intact.
     Any new dim level on this card has to be checked in DARK; light will always flatter it. */
  color: color-mix(in srgb, currentColor 64%, transparent);
}

/* ═══ 2 · THE WEEK ═════════════════════════════════════════════════════════ */

.nw-range {
  font: 500 12px/1 var(--font-ui); letter-spacing: .02em;
  font-variant-numeric: tabular-nums; color: var(--ink-tertiary);
}

.nw-strip {
  position: relative;              /* the offsetParent the thumb is measured against */
  display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px;
  margin: 0 16px 14px; padding: 3px;
  background: var(--bg-sunken); border-radius: 14px;
}

/* The sliding selection block. Positioned by JS (a spring), so no transition here —
   a CSS transition on top of a spring fights it and produces two motions at once. */
.nw-thumb {
  position: absolute; top: 3px; bottom: 3px; left: 0;
  background: var(--ink); border-radius: 11px;
  z-index: 0; will-change: transform;
}

.nw-day {
  position: relative; z-index: 1;
  display: flex; flex-direction: column; align-items: center; gap: 3px;
  border: 0; background: transparent; cursor: pointer;
  padding: 8px 0 7px; border-radius: 11px;
  color: var(--ink-secondary);
  touch-action: manipulation; -webkit-tap-highlight-color: transparent;
  transition: color var(--t-press) var(--ease-out);
}
.nw-day.is-on { color: var(--bg); }

.nw-dow {
  font: 600 9px/1 var(--font-ui); letter-spacing: .07em; text-transform: uppercase;
  opacity: .8;
}
/* Fraunces on the date. It is the one number on this screen you scan for. */
.nw-num {
  font-family: var(--font-display); font-weight: 600;
  font-size: 18px; line-height: 1; letter-spacing: -.02em;
  font-variant-numeric: tabular-nums;
}

.nw-bars { display: flex; gap: 2px; height: 3px; align-items: center; }
.nw-bars i {
  width: 4px; height: 3px; border-radius: 2px;
  background: currentColor; opacity: .55;
}
/* A closed day gets a rule, not an absent mark — an empty slot reads as a rendering bug. */
.nw-bars .nw-bar-none { width: 9px; height: 1.5px; opacity: .32; }

/* ── The selected day's detail ───────────────────────────────────────────── */
.nw-detail-head {
  display: flex; align-items: baseline; justify-content: space-between; gap: 10px;
  padding: 0 20px 8px;
}
.nw-detail-day {
  font: 600 13px/1.2 var(--font-ui); letter-spacing: -.004em;
  font-variant-numeric: tabular-nums; color: var(--ink);
}
.nw-detail-count {
  font: 500 12px/1 var(--font-ui); letter-spacing: .02em; color: var(--ink-tertiary);
  white-space: nowrap;
}

.nw-ses {
  margin: 0 16px;
  background: var(--bg-raised); border-radius: var(--r-lg);
  box-shadow: var(--shadow-1); overflow: hidden;
}
.nw-row {
  display: flex; align-items: flex-start; gap: 12px;
  padding: 13px 15px; border-bottom: 1px solid var(--rule);
}
.nw-row:last-child { border-bottom: 0; }

/* Fixed-width time column so seven days of start times line up down the card — the whole
   reason the block can be read at a glance instead of parsed row by row. */
.nw-time {
  flex: none; width: 62px; display: flex; flex-direction: column; gap: 2px;
  font-variant-numeric: tabular-nums;
}
.nw-time-a { font: 600 13px/1.2 var(--font-ui); color: var(--ink); }
.nw-time-b { font: 400 12px/1.2 var(--font-ui); color: var(--ink-tertiary); }

.nw-mid { flex: 1; min-width: 0; }
.nw-name {
  font-family: var(--font-display); font-weight: 600;
  font-size: 16px; line-height: 1.2; letter-spacing: -.01em; color: var(--ink);
}
.nw-tags { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 6px; }

/* A smaller sibling of shell.css's .tag. Not .tag itself: its 5px/9px padding is right for
   a single status pill and too heavy for three of them stacked in a dense timetable row. */
.nw-chip {
  display: inline-flex; align-items: center;
  font: 600 10px/1 var(--font-ui); letter-spacing: .05em; text-transform: uppercase;
  padding: 4px 7px; border-radius: var(--r-full);
  background: var(--bg-sunken); color: var(--ink-secondary);
  white-space: nowrap;
}
/* ⚠ SOLOS AND DUOS ARE WORDS FIRST. The tint is a second signal, never the only one: a
   player who reads the colour and not the word turns up to a duos night without a partner
   and cannot play at all. Both tints are quiet on purpose — orange belongs to the one
   thing you press, and chartreuse means a rally in progress. */
.nw-chip--solos {
  background: color-mix(in srgb, var(--ink) 8%, transparent);
  color: var(--ink-secondary);
}
.nw-chip--duos {
  background: color-mix(in srgb, var(--ink) 14%, transparent);
  color: var(--ink);
}
.nw-chip--members {
  background: color-mix(in srgb, var(--warn) 16%, transparent);
  color: var(--warn);
}
.nw-chip--full {
  background: color-mix(in srgb, var(--danger) 14%, transparent);
  color: var(--danger);
}

.nw-price {
  flex: none; align-self: center;
  font: 600 15px/1 var(--font-ui); letter-spacing: -.01em; color: var(--ink);
}

/* ⛔ The payment rule, in the venue's own voice. Quiet, but never removed. */
.nw-note {
  margin: 10px 20px 0;
  font: 400 12px/1.45 var(--font-ui); color: var(--ink-tertiary);
}

/* ═══ 3 · ANNOUNCEMENTS ════════════════════════════════════════════════════ */

.nw-posts {
  margin: 0 16px;
  background: var(--bg-raised); border-radius: var(--r-lg);
  box-shadow: var(--shadow-1); overflow: hidden;
}
.nw-post { border-bottom: 1px solid var(--rule); }
.nw-post:last-child { border-bottom: 0; }

.nw-post-hit {
  display: flex; align-items: flex-start; gap: 12px; width: 100%;
  border: 0; background: transparent; cursor: pointer; text-align: left;
  padding: 15px; min-height: var(--tap-min);
  touch-action: manipulation; -webkit-tap-highlight-color: transparent;
  transition: background-color var(--t-press) var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .nw-post-hit:hover { background: var(--bg-sunken); }
}

.nw-post-text { flex: 1; min-width: 0; }
.nw-post-meta { display: flex; align-items: center; gap: 8px; margin-bottom: 5px; }
.nw-post-date {
  font: 500 11px/1 var(--font-ui); letter-spacing: .03em; color: var(--ink-tertiary);
}
/* The category is set in small caps against a hairline, the way a paper labels a column.
   No per-category colour: four tinted chips on a quiet screen is a decoration budget spent
   on the least useful fact in the row. */
.nw-post-cat {
  font: 600 10px/1 var(--font-ui); letter-spacing: .09em; text-transform: uppercase;
  color: var(--ink-tertiary);
  padding-left: 8px; border-left: 1px solid var(--rule);
}

/* h3 is Inter everywhere else in the app. Here it is Fraunces, because a headline set in
   the UI face reads as a label and a headline set in the serif reads as something a person
   wrote. This screen is the one place that difference is the point. */
.nw-post-head {
  font-family: var(--font-display); font-weight: 600;
  font-size: 17px; line-height: 1.24; letter-spacing: -.012em;
  color: var(--ink); margin: 0; text-wrap: pretty;
}

.nw-chev {
  flex: none; margin-top: 3px; color: var(--ink-tertiary); opacity: .55;
  transform-origin: center;
}
.nw-chev svg { width: 17px; height: 17px; display: block; }
.nw-post.is-open .nw-chev { transform: rotate(180deg); }

/* ⚠ 0fr → 1fr, THE SAME EXCEPTION shell.css MAKES FOR THE NAV LABELS, AND FOR THE SAME
   REASON. The house rule is that only transform and opacity animate, and a disclosure has
   to change height — `height: auto` cannot be transitioned at all, and a max-height guess
   is wrong at some text size, in some language, on some phone, where it either clips the
   last line or leaves a gap that reads as broken. A grid row animates to the content's
   real height, whatever it turns out to be. The inner element MUST keep min-width/height 0
   and overflow hidden or the text refuses to be squeezed and the row jumps open. */
[data-ready] .nw-post-body {
  transition: grid-template-rows var(--t-exit) var(--ease-out),
              opacity var(--t-exit) var(--ease-out);
}
[data-ready] .nw-post.is-open .nw-post-body {
  transition-duration: var(--t-menu);   /* ⚠ exit is faster than enter, always */
}
[data-ready] .nw-chev {
  transition: transform var(--t-menu) var(--ease-out);
}

.nw-post-body { display: grid; grid-template-rows: 0fr; opacity: 0; }
.nw-post.is-open .nw-post-body { grid-template-rows: 1fr; opacity: 1; }
.nw-post-inner { min-height: 0; overflow: hidden; }
.nw-post-inner p {
  margin: 0; padding: 0 15px 16px 15px;
  font: 400 15px/1.52 var(--font-ui); color: var(--ink-secondary);
  max-width: 62ch;
}

.nw-sign {
  margin: 18px 20px 0; text-align: center;
  font-family: var(--font-display); font-style: italic;
  font-size: var(--caption-size); letter-spacing: var(--caption-track);
  color: var(--ink-tertiary);
}

/* ═══ 4 · ACCESSIBILITY ════════════════════════════════════════════════════
 * Reduced motion is a gentler equivalent, not an absent one. Naming this file's own
 * animations, per DESIGN.md §4.8: the week thumb (a JS spring — motion.js already snaps it,
 * so nothing to do here), the disclosure row, and the chevron.
 */
@media (prefers-reduced-motion: reduce) {
  [data-ready] .nw-post-body { transition-property: opacity; }
  [data-ready] .nw-post.is-open .nw-post-body { transition-property: opacity; }
  [data-ready] .nw-chev { transition: none; }
  .nw-post.is-open .nw-chev { transform: none; }
  /* The chevron still has to say which way it points, so with rotation gone it says it in
     opacity — the open row's marker is the solid one. */
  .nw-post.is-open .nw-chev { opacity: 1; }
}

@media (prefers-contrast: more) {
  .nw-chip { outline: 1px solid var(--ink-secondary); }
  .nw-thumb { background: var(--ink); }
  .nw-pin { outline: 2px solid var(--ink); outline-offset: -2px; }
}
