/* =====================================================================
   DAILY PUZZLE — shared component styles.

   GENERATED COPIES OF THIS FILE LIVE IN SITE REPOSITORIES. The source is
   puzzle-books/web/grid/daily-grid.css.

   Every colour and every typeface is a variable defined by the consuming
   site's tokens file. There is not one brand literal in here, which is
   what lets a second series adopt the grid by writing tokens rather than
   by forking a stylesheet.

   Spacing follows the host site's 8px rhythm.
   ===================================================================== */

.daily {
  /* Cell geometry is the whole responsive story. One variable, three
     breakpoints, and the table inherits the rest.

     The 36px floor is deliberate and is what forces the scroller on a
     narrow phone. Letting the cells shrink to fit 320px instead gives a
     30px target: legal under WCAG 2.5.8, and still too small to mark
     reliably with a thumb, on a book whose readership is why the series
     ships a large-print edition. Scrolling a grid is a minor cost; a
     mis-tapped cell in a deduction puzzle is a wrong answer the solver
     cannot debug. */
  --daily-cell: clamp(36px, 9.6vw, 44px);
  --daily-rowlab: clamp(62px, 18vw, 92px);
  --daily-rail: 20px;
  --daily-head: 86px;
}

@media (min-width: 700px) {
  .daily { --daily-cell: 44px; --daily-rowlab: 96px; --daily-rail: 24px; --daily-head: 96px; }
}

@media (min-width: 1100px) {
  .daily { --daily-cell: 50px; --daily-rowlab: 108px; --daily-head: 104px; }
}

/* ------------------------------------------------------------- masthead */

.daily-head { padding: 40px 0 0; }

.daily-head__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 8px 16px;
  margin: 8px 0 0;
  font-family: var(--font-data);
  font-size: 13px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-muted);
}

.daily-head__meta strong { color: var(--ink); font-weight: 500; }

.daily-title {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(28px, 4.6vw, 40px);
  line-height: 1.15;
  letter-spacing: -0.01em;
  margin: 8px 0 0;
  text-wrap: balance;
}

.daily-scenario {
  margin: 16px 0 0;
  max-width: 62ch;
  font-size: 18px;
  color: var(--ink-muted);
}

/* --------------------------------------------------------------- layout */

/* One column on a phone, two from 1000px. The desktop rule is the point:
   a wide screen gets a readable clue measure beside a generous grid, not
   a phone column floating in the middle of a 1440px page. */
.daily-layout {
  display: grid;
  grid-template-columns: 1fr;
  gap: 32px;
  margin-top: 32px;
  align-items: start;
}

.daily-layout > * { min-width: 0; }

@media (min-width: 1000px) {
  .daily-layout {
    grid-template-columns: minmax(0, 27rem) minmax(0, 1fr);
    gap: 48px;
  }
  /* The grid stays put while a long clue list scrolls past it. Marking a
     cell you have to scroll back up to find is the reason. */
  .daily-panel--grid { position: sticky; top: 88px; }
  /* The grid has its own column at this width and does not scroll
     sideways, so the notice about that is noise -- and one line of noise
     between the heading and the grid is what misaligned the two panels. */
  .daily-hint--narrow { display: none; }
}

.daily-panel h2 {
  font-family: var(--font-display);
  font-size: 20px;
  font-weight: 600;
  margin: 0;
}

.daily-hint {
  margin: 8px 0 0;
  font-size: 15px;
  color: var(--ink-muted);
  max-width: 60ch;
}

/* ---------------------------------------------------------------- clues */

.daily-clues {
  margin: 16px 0 0;
  padding: 0 0 0 24px;
  font-size: 16px;
  max-width: 62ch;
}

.daily-clues li {
  margin-bottom: 12px;
  padding-left: 4px;
}

.daily-clues li::marker {
  font-family: var(--font-data);
  color: var(--accent);
}

/* ----------------------------------------------------------- shared help */

/* The help block sits ABOVE the two columns, and that placement is the
   whole fix. While the interaction paragraph lived in the grid panel it
   pushed the grid itself a paragraph below the start of the clue list on
   every laptop: the two headings lined up, and the two things a solver
   actually reads did not.

   The marking key stays open because it is three glyphs and it is what a
   first-time solver needs; the longer guidance collapses because it is
   read once and then never again. */
.daily-help {
  display: grid;
  grid-template-columns: 1fr;
  gap: 12px;
  align-items: start;
  margin: 24px 0 0;
}

.daily-help > * { min-width: 0; }

@media (min-width: 700px) {
  .daily-help {
    grid-template-columns: auto minmax(0, 1fr);
    gap: 16px 24px;
    align-items: start;
  }
}

.daily-help__more {
  background: var(--surface);
  border: 1px solid var(--rule);
  border-radius: 8px;
}

.daily-help__summary {
  cursor: pointer;
  padding: 16px;
  font-family: var(--font-display);
  font-size: 16px;
  font-weight: 600;
  color: var(--ink);
}

.daily-help__summary:focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: -3px;
  border-radius: 8px;
}

.daily-help__body { padding: 0 16px 16px; }

.daily-help__body p {
  margin: 0 0 12px;
  font-size: 15px;
  line-height: 1.6;
  color: var(--ink-muted);
  max-width: 68ch;
}

.daily-help__body p:last-child { margin-bottom: 0; }

.daily-legend {
  margin: 0;
  padding: 16px;
  background: var(--surface);
  border: 1px solid var(--rule);
  border-radius: 8px;
}

.daily-legend h3 {
  font-family: var(--font-display);
  font-size: 16px;
  font-weight: 600;
  margin: 0 0 8px;
}

.daily-legend dl {
  margin: 0;
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 4px 12px;
  font-size: 15px;
}

.daily-legend dt {
  font-family: var(--font-data);
  font-weight: 500;
  color: var(--ink);
}

.daily-legend dd { margin: 0; color: var(--ink-muted); }

/* On a laptop the key is more useful as one compact line than as another
   card-height block. Keep this query after the base legend rules so those
   rules cannot accidentally turn it back into three rows. */
@media (min-width: 1100px) {
  .daily-head { padding-top: 32px; }

  .daily-help {
    grid-template-columns: minmax(0, 3fr) minmax(190px, 1fr);
    margin-top: 16px;
  }

  .daily-layout { margin-top: 24px; }

  .daily-legend {
    display: flex;
    align-items: center;
    gap: 18px;
    padding: 12px 16px;
  }

  .daily-legend h3 {
    margin: 0;
    white-space: nowrap;
  }

  .daily-legend dl {
    grid-template-columns: repeat(3, auto auto);
    align-items: center;
    gap: 4px 9px;
  }

  .daily-help__summary { padding: 14px 16px; }
}

/* ----------------------------------------------------------------- grid */

/* A controlled scroller, not page overflow. `max-width: 100%` on the
   wrapper plus `min-width: 0` on the layout children is what keeps a
   320px viewport from growing a horizontal scrollbar of its own. */
.daily-grid-scroll {
  max-width: 100%;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  -webkit-overflow-scrolling: touch;
  padding-bottom: 8px;
}

.daily-grid-scroll:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }

.daily-grid {
  border-collapse: collapse;
  table-layout: fixed;
  margin: 16px 0 0;
}

.daily-grid th,
.daily-grid td {
  width: var(--daily-cell);
  height: var(--daily-cell);
  padding: 0;
  border: 1px solid var(--rule);
  text-align: center;
  vertical-align: middle;
}

.daily-grid__corner,
.daily-grid__void {
  border: none !important;
  background: transparent !important;
}

.daily-grid__band {
  border: none !important;
  font-family: var(--font-data);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-muted);
  height: 24px;
  padding-bottom: 4px !important;
}

.daily-grid__rail {
  border: none !important;
  width: var(--daily-rail);
  padding: 0 !important;
}

.daily-grid__rail span {
  display: block;
  writing-mode: vertical-rl;
  transform: rotate(180deg);
  font-family: var(--font-data);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-muted);
  white-space: nowrap;
}

.daily-grid__col {
  height: var(--daily-head);
  background: var(--surface);
  vertical-align: bottom;
}

.daily-grid__rot {
  display: inline-block;
  writing-mode: vertical-rl;
  transform: rotate(180deg);
  font-family: var(--font-data);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.04em;
  color: var(--ink);
  white-space: nowrap;
  padding: 6px 0;
}

.daily-grid__row {
  width: var(--daily-rowlab);
  background: var(--surface);
  font-family: var(--font-data);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.04em;
  color: var(--ink);
  text-align: right;
  padding: 0 8px !important;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.daily-grid__cell { background: var(--ground); }

/* The stepped outer boundary. Assigned from computed classes, never from
   an nth-child pattern — a pattern is right for one category count and
   quietly wrong for the next. */
.daily-grid .edge-t:not(.daily-grid__void) { border-top: 2px solid var(--rule-strong); }
.daily-grid .edge-b:not(.daily-grid__void) { border-bottom: 2px solid var(--rule-strong); }
.daily-grid .edge-l:not(.daily-grid__void) { border-left: 2px solid var(--rule-strong); }
.daily-grid .edge-r:not(.daily-grid__void) { border-right: 2px solid var(--rule-strong); }

/* ----------------------------------------------------------------- cell */

.daily-cell {
  display: block;
  width: 100%;
  height: 100%;
  min-width: var(--daily-cell);
  min-height: var(--daily-cell);
  margin: 0;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--ink);
  font-family: var(--font-body);
  font-size: calc(var(--daily-cell) * 0.44);
  line-height: 1;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.daily-cell:hover { background: var(--surface-2); }

.daily-cell:focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: -3px;
}

/* A confirmed pairing is the rare mark, and it earns the accent. The
   symbol carries the meaning on its own: greyscale, high-contrast mode
   and colour blindness all still read ● against ✕. */
.daily-cell[data-state="circle"] {
  color: var(--accent);
  background: var(--accent-soft);
  font-weight: 600;
}

.daily-cell[data-state="cross"] { color: var(--ink-muted); }

/* -------------------------------------------------------------- controls */

.daily-controls {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 24px;
}

/* Beside the button that produced it, and visible enough to be believed.
   An unstyled sentence under a control is a sentence readers scroll past
   and then report as "Check did nothing". */
.daily-message {
  margin: 16px 0 0;
  min-height: 1.65em;
  font-size: 16px;
  color: var(--ink);
}

.daily-message[data-state] {
  padding: 12px 16px;
  border: 1px solid var(--rule);
  border-left: 4px solid var(--rule-strong);
  border-radius: 8px;
  background: var(--surface);
  min-height: 0;
}

/* Not yet right, and saying so plainly. Still spoiler-free: the text
   names a state, never a cell. */
.daily-message[data-state="warn"] {
  border-left-color: var(--accent);
  font-weight: 500;
}

.daily-note {
  margin: 16px 0 0;
  padding: 12px 16px;
  border-left: 3px solid var(--rule-strong);
  background: var(--surface);
  font-size: 15px;
  color: var(--ink-muted);
}

/* The one moment the page is allowed to raise its voice. A solved case
   used to land as a quiet grey panel below the fold; this is the accent
   border, the larger heading and the shadow that make it unmissable
   without a single pixel of confetti. */
.daily-result {
  margin: 24px 0 0;
  padding: 24px;
  background: var(--surface);
  border: 2px solid var(--accent);
  border-left-width: 8px;
  border-radius: 10px;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.10);
}

/* The card takes programmatic focus when a case closes, so it has to show
   where focus went. :focus, not :focus-visible: focus arrives here from a
   script, and a ring that only appears for keyboard users would leave the
   pointer user's focus invisible. */
.daily-result:focus {
  outline: 3px solid var(--focus);
  outline-offset: 3px;
}

.daily-result h2 {
  font-family: var(--font-display);
  font-size: clamp(22px, 3vw, 28px);
  font-weight: 700;
  line-height: 1.2;
  color: var(--accent);
  margin: 0;
}

.daily-result p { margin: 8px 0 0; font-size: 16px; }

.daily-result__streak { color: var(--ink-muted); }

.daily-share-status {
  margin: 8px 0 0;
  font-size: 15px;
  color: var(--ink-muted);
  min-height: 1.65em;
}

/* -------------------------------------------------------------- archive */

.daily-archive {
  margin: 32px 0 0;
  padding: 0;
  list-style: none;
  display: grid;
  grid-template-columns: 1fr;
  gap: 8px;
}

@media (min-width: 700px) {
  .daily-archive { grid-template-columns: repeat(2, 1fr); }
}

.daily-archive__item {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 12px;
  padding: 16px;
  background: var(--surface);
  border: 1px solid var(--rule);
  border-radius: 8px;
}

.daily-archive__item a {
  font-family: var(--font-display);
  font-size: 17px;
  font-weight: 600;
  color: var(--ink);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.daily-archive__no {
  font-family: var(--font-data);
  font-size: 12px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-muted);
  width: 100%;
}

.daily-archive__done {
  font-family: var(--font-data);
  font-size: 12px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--accent);
}

/* ------------------------------------------------------ homepage feature */

.daily-feature {
  margin: 0;
  padding: 32px 24px;
  background: var(--surface);
  border: 1px solid var(--rule);
  border-radius: 10px;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);
}

/* Three things to balance below the book hero: what it is, what it looks
   like, and the way in. On a phone they stack in that order, so the
   reading never depends on the picture. */
.daily-feature__grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 24px;
  align-items: center;
}

@media (min-width: 900px) {
  .daily-feature__grid {
    grid-template-columns: minmax(0, 1.25fr) minmax(0, 0.8fr) minmax(0, 0.7fr);
    gap: 32px;
  }
}

.daily-feature__grid > * { min-width: 0; }

/* An illustration, not a preview. It is hand-drawn, identical every day,
   and shows no part of any real case -- a homepage that leaked today's
   first deduction would be giving the puzzle away to sell it. */
.daily-feature__visual {
  display: block;
  width: 100%;
  max-width: 260px;
  height: auto;
  margin: 0 auto;
}

/* Styled from here rather than from presentation attributes on the shapes,
   so every line and mark reads from the same tokens the real grid does and
   follows the site into dark mode. */
.daily-feature__visual .v-rule,
.daily-feature__visual .v-edge { fill: none; }
.daily-feature__visual .v-rule { stroke: var(--rule); stroke-width: 1; }
.daily-feature__visual .v-edge { stroke: var(--rule-strong); stroke-width: 2; }

.daily-feature__visual .v-label {
  font-family: var(--font-data);
  font-size: 9px;
  fill: var(--ink-muted);
}

.daily-feature__visual .v-dot { fill: var(--accent); }

.daily-feature__visual .v-cross {
  fill: none;
  stroke: var(--ink-muted);
  stroke-width: 2;
  stroke-linecap: round;
}

.daily-feature h2 {
  font-family: var(--font-display);
  font-size: clamp(24px, 3.4vw, 32px);
  font-weight: 700;
  line-height: 1.2;
  margin: 8px 0 0;
}

.daily-feature p { margin: 12px 0 0; max-width: 56ch; color: var(--ink-muted); }

.daily-feature__meta {
  margin: 16px 0 0;
  font-family: var(--font-data);
  font-size: 13px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink);
}

.daily-feature__actions { margin-top: 24px; }

/* ---------------------------------------------------------------- a11y */

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

@media (prefers-reduced-motion: reduce) {
  .daily-grid-scroll { scroll-behavior: auto; }
}

@media (max-width: 420px) {
  .daily-controls .btn { flex: 1 1 100%; }
  .daily-head { padding-top: 24px; }
}

/* A short laptop viewport still needs to reveal the first playable row with
   the clues. Keep every masthead element, but tighten typography and rhythm
   only when the desktop viewport is no taller than the reported 634px case. */
@media (min-width: 1100px) and (max-height: 700px) {
  .daily-title { font-size: 28px; }
  .daily-scenario { margin-top: 8px; font-size: 16px; line-height: 1.35; }
  .daily-case-brief { margin-top: 8px; margin-bottom: 0; font-size: 15px; line-height: 1.35; }
  .daily-help { margin-top: 8px; }
  .daily-layout { margin-top: 16px; }
}
