/* ─────────────────────────────────────────────────────────────────────────
 * Notifications page.
 *
 * ⚠ This lived as a 111-line inline <style> in the view. It was moved here because the whole
 * layout is media-query work, and an inline rule cannot be reached by a media query — the single
 * most repeated defect in this codebase (CLAUDE.md, "the inline-style trap"). Keep it here.
 *
 * ⚠ Stylesheets are linked ALPHABETICALLY by `stylesheet_link_tag :app`, so this file loads
 * BEFORE tailwind.css. A Tailwind utility on these elements beats a single-class rule here — go
 * two classes deep rather than reaching for !important.
 *
 * ⚠ The page's JS drives tabs, dismissal and clear-all off data attributes:
 *   [data-notifications] [data-clear-all] .notif-tab[data-tab] .notif-cat[data-cat]
 *   .notif-row[data-key] [data-count-for] [data-empty-for]
 * Restyle freely; do not rename those.
 * ───────────────────────────────────────────────────────────────────────── */

/* ── Shell ───────────────────────────────────────────────────────────────
   Was `max-width: 760px` at every width, which left 436px of dead space EACH SIDE inside a
   1632px content area at 1920. It is now a grid: the list, and a rail that gives that space a
   job (the weekly digest, and the preferences panel when it lands).
   minmax(0, …) on the list track is required — a bare 1fr has an auto minimum, so one long
   fixture name would grow the track instead of ellipsing inside it. */
.notif-wrap { max-width: 1280px; margin: 0 auto; }

/* ⚠ 1400px, not 1100. The breakpoint has to account for the ~288px sidebar: at a 1100px
   VIEWPORT the content area is only 812px, so splitting off a 300px rail left a 484px list —
   narrower than the 760px column this change set out to widen, and it put the tabs back into
   overflow with 8 of 11 titles truncated. Measured, not guessed. */
@media (min-width: 1400px) {
  .notif-wrap {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 300px;
    grid-template-areas: "head head" "list rail";
    column-gap: 28px; align-items: start;
  }
  .notif-head  { grid-area: head; }
  .notif-lists { grid-area: list; min-width: 0; }
  .notif-rail  { grid-area: rail; position: sticky; top: 88px; }
}

/* Below the two-column breakpoint the rail is just a block in the flow, and source order would
   drop the weekly summary at the BOTTOM of the page — after 26 rows, where nobody would see it.
   It is a standing summary, so it belongs above the list, which is where it sat before. */
@media (max-width: 1399px) {
  .notif-wrap  { display: flex; flex-direction: column; }
  .notif-head  { order: 0; }
  .notif-rail  { order: 1; }
  .notif-lists { order: 2; }
}

/* ── Running head ────────────────────────────────────────────────────────
   The same editorial device as the home page's desk head: serif name at one end, gold dateline
   at the other, double rule beneath. Replaces a stacked eyebrow + title + subtitle + a boxed
   button on its own row, which cost ~60px above the fold on a phone. */
.notif-head {
  display: flex; align-items: baseline; justify-content: space-between; gap: 16px;
  border-bottom: 4px double var(--hh-ink, var(--text-primary));
  padding-bottom: 12px; margin-bottom: 18px;
}
/* ⚠ TWO classes deep on purpose. theme_hallmark.css carries a blanket
   `body.hallmark h1, h2, h3 { font-family: var(--hh-display) }` at (0,1,1), which beats a plain
   `.notif-title` at (0,1,0) — the serif silently rendered as Archivo until this was scoped.
   Not Tailwind, which is what the header comment above would have led you to suspect. This is
   the same reason .hh-desk-title works on the home page. */
body.hallmark .notif-title,
.notif-title {
  /* Same treatment as the home page's .hh-desk-title, so the two page heads read as one system
     and both echo the wordmark. See the long note there for why it is uppercase and tracked.
     ⚠ Smaller ceiling than the home head on purpose: "NOTIFICATIONS" is 13 characters against
     "GAMEDAY"'s 7, and this row shares its width with the count and Clear-all. Sized from
     measurement at 320px, not copied across. */
  font-family: var(--hh-display, var(--font-sans));
  font-weight: 800; letter-spacing: 0.06em;
  text-transform: uppercase;
  font-size: clamp(19px, 1.6vw + 12px, 28px);
  line-height: 1.1; color: var(--hh-ink, var(--text-primary));
  margin: 0; min-width: 0; overflow-wrap: anywhere;
}
.notif-meta {
  display: flex; align-items: baseline; gap: 14px;
  flex: none; white-space: nowrap;
}
.notif-count {
  font-family: var(--hh-mono, monospace); font-size: 11px; letter-spacing: 2px;
  text-transform: uppercase; color: var(--hh-accent-2, var(--accent-warning));
}
/* A quiet text action, not a boxed button — it sat on its own row on a phone. */
.notif-clear {
  font-family: var(--hh-mono, monospace); font-size: 11px; font-weight: 700;
  letter-spacing: 1px; text-transform: uppercase; color: var(--text-muted);
  background: transparent; border: 0; border-bottom: 1px solid transparent;
  padding: 0 0 1px; cursor: pointer; white-space: nowrap; transition: color .12s ease, border-color .12s ease;
}
.notif-clear:hover { color: var(--accent-danger, #ef4444); border-bottom-color: currentColor; }

/* ── Tabs ────────────────────────────────────────────────────────────────
   Four tabs needed 471px in a 353px rail at 393px, so one scrolled off with NO affordance —
   "Account" was simply invisible. On a phone they become a 2×2 grid: all four visible, nothing
   to scroll, no affordance needed. Stays a row from 768px up, where it always fitted. */
.notif-tabs {
  display: flex; gap: 4px; border-bottom: 1px solid var(--hh-rule, var(--border));
  margin-bottom: 16px;
}
.notif-tab {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  white-space: nowrap; padding: 10px 14px; font-size: 13px; font-weight: 600; cursor: pointer;
  color: var(--text-secondary); background: transparent; border: none;
  border-bottom: 2px solid transparent; margin-bottom: -1px; transition: color .12s ease;
}
.notif-tab:hover { color: var(--text-primary); }
.notif-tab.active { color: var(--text-primary); font-weight: 700; border-bottom-color: var(--hh-accent); }
.notif-tab-count {
  font-family: var(--hh-mono, monospace); font-size: 11px; font-weight: 700;
  color: var(--text-muted); background: var(--bg-tertiary); border-radius: 20px;
  padding: 1px 7px; min-width: 20px; text-align: center;
}
.notif-tab.active .notif-tab-count { color: var(--hh-accent); }

@media (max-width: 767px) {
  .notif-tabs {
    display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 6px; border-bottom: none; margin-bottom: 14px;
  }
  .notif-tab {
    justify-content: space-between; border: 1px solid var(--hh-rule, var(--border));
    border-radius: 9px; margin-bottom: 0; padding: 9px 12px; min-height: 44px;
  }
  .notif-tab.active {
    border-color: var(--hh-accent);
    background: color-mix(in oklab, var(--hh-accent) 12%, transparent);
  }
  /* color-mix must be guarded: unsupported browsers drop the WHOLE declaration it sits in. */
  @supports not (background: color-mix(in oklab, red 10%, transparent)) {
    .notif-tab.active { background: var(--bg-tertiary); }
  }
}

.notif-cat { display: none; }
.notif-cat.active { display: block; }

/* ── Day headers ─────────────────────────────────────────────────────────
   Inserted by JS as direct children of .notif-card, not rendered by the server: times render in
   the VIEWER's zone via local_time_tag, so only the client knows which day a row falls on.
   No visibility gate is needed — with JS off no header is ever created, so the failure mode is
   "no grouping" rather than an empty label. */
.notif-dayhead {
  font-family: var(--hh-mono, monospace); font-size: 10.5px; font-weight: 700;
  letter-spacing: 1.6px; text-transform: uppercase; color: var(--hh-accent-2, var(--accent-warning));
  padding: 16px 2px 7px; display: flex; align-items: center; gap: 10px;
}
.notif-dayhead::after {
  content: ""; flex: 1; height: 1px; background: var(--hh-rule, var(--border)); opacity: .7;
}
.notif-card > .notif-dayhead:first-child { padding-top: 4px; }

.notif-card {
  background: var(--bg-secondary); border: 1px solid var(--hh-rule, var(--border));
  border-radius: 10px; overflow: hidden;
}

/* ── Rows ────────────────────────────────────────────────────────────────
   The title used to be nowrap+ellipsis and shared its line with the timestamp: 9 of 26 titles
   were cut on a phone. It now takes the full width over up to two lines, and the time drops
   below as meta. Desktop keeps the time on the right, where there is room for it. */
.notif-row {
  display: flex; align-items: center; gap: 8px;
  padding: 12px 12px 12px 0; border-bottom: 1px solid var(--hh-rule, var(--border));
  transition: background .12s ease;
}
.notif-row:last-child { border-bottom: none; }
.notif-row:hover { background: var(--bg-tertiary); }

.notif-link {
  flex: 1 1 auto; min-width: 0; display: flex; align-items: center; gap: 14px;
  text-decoration: none; color: inherit; padding-left: 13px;
}
.notif-accent { width: 3px; align-self: stretch; border-radius: 0 3px 3px 0; flex: 0 0 auto; }

.notif-icon {
  flex: 0 0 auto; width: 40px; height: 40px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center; font-size: 19px;
  background: var(--bg-tertiary); border: 1px solid var(--hh-rule, var(--border)); overflow: hidden;
}
.notif-icon img { width: 100%; height: 100%; object-fit: contain; padding: 4px; }

.notif-body { flex: 1 1 auto; min-width: 0; }
.notif-row-title {
  font-size: 14px; font-weight: 700; color: var(--text-primary);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.notif-row-sub {
  font-size: 12.5px; color: var(--text-secondary); margin-top: 2px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* Inline copy of the timestamp, shown only on a phone where the right-hand slot is gone. */
.notif-row-when { display: none; }
/* --text-muted measures 4.32:1 on the card at this size — under the 4.5 AA floor for small
   text. --text-secondary is the same role one step up, at 6.91:1. */
.notif-time {
  flex: 0 0 auto; font-family: var(--hh-mono, monospace); font-size: 11px;
  color: var(--text-secondary); white-space: nowrap;
}
.notif-x {
  flex: 0 0 auto; width: 34px; height: 34px; margin-right: 4px; border-radius: 7px;
  display: flex; align-items: center; justify-content: center; cursor: pointer;
  background: transparent; border: none; color: var(--text-muted); font-size: 20px;
  line-height: 1; transition: all .12s ease;
}
.notif-x:hover { background: rgba(239, 68, 68, 0.12); color: var(--accent-danger, #ef4444); }

.notif-cat-empty {
  text-align: center; padding: 30px 20px; color: var(--text-muted); font-size: 13px;
}

.notif-empty { text-align: center; padding: 48px 24px; color: var(--text-secondary); }
.notif-empty .e-emoji { font-size: 34px; }
.notif-empty .e-title { font-size: 17px; font-weight: 700; color: var(--text-primary); margin: 12px 0 6px; }
.notif-empty .e-body { font-size: 13.5px; }
.notif-empty a { color: var(--hh-accent); font-weight: 600; }

/* ── Rail — the weekly digest, and later the preferences panel ───────────── */
.notif-digest {
  display: flex; align-items: flex-start; gap: 14px;
  padding: 16px 18px; margin-bottom: 14px;
}
.notif-digest-emoji { font-size: 22px; line-height: 1; flex: none; }
.notif-digest-title { font-weight: 700; font-size: 14px; color: var(--text-primary); }
.notif-digest-sub { font-size: 13px; color: var(--text-secondary); margin-top: 3px; line-height: 1.5; }

@media (min-width: 1400px) {
  .notif-digest { flex-direction: column; gap: 8px; margin-bottom: 0; }
}

/* The title takes its own row once it can no longer share one with the count and Clear-all.
   Measured: at 320px "NOTIFICATIONS" wants ~180px and the meta ~150px against 288px of content,
   so sharing the row wrapped the TITLE onto two lines — worse than simply stacking them. Shrinking
   the type instead would have had to go below 15px to fit, which is not a page title any more. */
@media (max-width: 430px) {
  .notif-head { flex-wrap: wrap; }
  .notif-title { flex: 1 1 100%; }
}

/* ── Phone ───────────────────────────────────────────────────────────────── */
@media (max-width: 767px) {
  .notif-row { gap: 4px; align-items: flex-start; padding: 12px 10px 12px 0; }
  .notif-link { gap: 11px; padding-left: 11px; align-items: flex-start; }
  .notif-icon { width: 34px; height: 34px; font-size: 16px; margin-top: 1px; }

  /* Two lines, then ellipsis — nothing is silently cut at one line any more. */
  .notif-row-title {
    white-space: normal; overflow-wrap: anywhere; line-height: 1.3;
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
  }
  .notif-row-sub { white-space: normal; line-height: 1.35; }
  /* The right-hand time slot is dropped and re-shown under the subtitle instead. */
  .notif-time { display: none; }
  .notif-row-when {
    display: block; font-family: var(--hh-mono, monospace); font-size: 10.5px;
    color: var(--text-secondary); margin-top: 4px; letter-spacing: .4px;
  }
  .notif-x { width: 40px; height: 40px; margin-top: -3px; }
}

/* The smallest phones need a third line: at 320px a title like "Full time: Chelsea FC 4–3
   Brighton & Hove Albion FC" lays out over 3 lines, and clamping at 2 CUT it — invisible to a
   scrollWidth check, which only ever sees horizontal overflow. */
@media (max-width: 360px) {
  .notif-row-title { -webkit-line-clamp: 3; }
}

/* ── Preferences panel ────────────────────────────────────────────────────
   A <details> so it costs one line closed and needs no JS to open. The list is grouped by the
   same four categories as the tabs, so the control reads in the shape of the thing it controls. */
.notif-prefs { margin-top: 14px; }
.notif-prefs > summary {
  list-style: none; cursor: pointer; padding: 14px 16px;
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  font-size: 13px; font-weight: 700; color: var(--text-primary);
}
.notif-prefs > summary::-webkit-details-marker { display: none; }
.notif-prefs > summary::after {
  content: "▸"; color: var(--hh-accent); transition: transform .15s ease; flex: none;
}
.notif-prefs[open] > summary::after { transform: rotate(90deg); }
.notif-prefs-muted {
  font-family: var(--hh-mono, monospace); font-size: 11px; font-weight: 700;
  color: var(--text-secondary); background: var(--bg-tertiary);
  border-radius: 20px; padding: 1px 7px; min-width: 20px; text-align: center;
}
.notif-prefs-muted:empty, .notif-prefs-muted:not(:empty) { margin-left: auto; }
.notif-prefs-body { padding: 0 16px 14px; }
.notif-prefs-group + .notif-prefs-group { margin-top: 14px; }
.notif-prefs-cat {
  font-family: var(--hh-mono, monospace); font-size: 10px; font-weight: 700;
  letter-spacing: 1.4px; text-transform: uppercase; color: var(--hh-accent-2, var(--accent-warning));
  padding-bottom: 6px; margin-bottom: 4px; border-bottom: 1px solid var(--hh-rule, var(--border));
}
.notif-pref {
  display: flex; align-items: center; gap: 10px;
  padding: 7px 0; font-size: 13px; color: var(--text-secondary); cursor: pointer;
  min-height: 34px;
}
.notif-pref input { accent-color: var(--hh-accent); width: 16px; height: 16px; flex: none; cursor: pointer; }
.notif-pref:hover { color: var(--text-primary); }
.notif-prefs-note { font-size: 11.5px; color: var(--text-muted); margin: 12px 0 0; }

/* On a phone the rail sits above the list, so the panel must start CLOSED and stay compact —
   thirteen checkboxes ahead of the feed would bury the thing the page is for. */
@media (max-width: 1399px) {
  .notif-prefs { margin-top: 0; margin-bottom: 14px; }
}

/* Link out to the full settings page in Profile. Same store, fuller presentation. */
.notif-prefs-more { margin: 10px 0 0; }
.notif-prefs-more a {
  font-family: var(--hh-mono, monospace); font-size: 11px; font-weight: 700;
  letter-spacing: .6px; color: var(--hh-accent); text-decoration: none;
}
.notif-prefs-more a:hover { text-decoration: underline; }
