/*
 * site.css — chrome around the puzzles (header, footer, index page), the
 * Inter webfont, and the light-mode lock.
 *
 * Loaded after exolve-m.css and exolve-mobile.css, so it wins ties.
 */

/* ---------------------------------------------------------------------------
 * Inter, self-hosted from the exolve image.
 *
 * One variable file covering 100-900. font-display:swap so the puzzle is
 * readable in the fallback face immediately rather than blocking on 344KB
 * over a phone connection.
 * ------------------------------------------------------------------------ */
@font-face {
  font-family: "InterVariable";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("/assets/fonts/InterVariable.woff2") format("woff2");
}

/* ---------------------------------------------------------------------------
 * Light mode, forced.
 *
 * `only light` rather than plain `light`: it is the opt-out that also stops
 * Chrome and Brave on Android applying their "force dark" auto-darkening to
 * a page that never asked for it. Plain `light` still leaves the page
 * eligible for that transform.
 * ------------------------------------------------------------------------ */
:root {
  color-scheme: only light;
}

/* ---------------------------------------------------------------------------
 * Inter everywhere inside the puzzle.
 *
 * Exolve hard-codes serif on .xlv-frame and monospace on ten-odd classes,
 * several with !important (exolve-m.css:16, 37, 46, 373, 406, 580, 667, 713).
 * A puzzle can also set `exolve-option: font-family`, which Exolve applies as
 * an *inline* style on the frame. Overriding all of that needs both the
 * universal selector and !important -- anything less leaves the clue list in
 * serif and the status line in monospace.
 * ------------------------------------------------------------------------ */
.xlv-frame,
.xlv-frame * {
  font-family: "InterVariable", system-ui, -apple-system, "Segoe UI", sans-serif !important;
}

/* ...except the grid itself, which keeps Exolve's own face.
 *
 * Upstream sets sans-serif on .xlv-cell-text and .xlv-cell-num
 * (exolve-m.css:127,130). Inter reads noticeably lighter than the platform
 * sans at grid sizes, so solution letters lose weight against the cell
 * borders. The selector above is deliberately broad, so this has to put the
 * grid back rather than carve it out of the exclusion.
 */
.xlv-frame .xlv-cell-text,
.xlv-frame .xlv-cell-num {
  font-family: sans-serif !important;
}

/* Tabular figures stop the progress counter jittering as it changes.
   Deliberately not applied to .xlv-cell-num: the grid stays untouched. */
.xlv-status,
.xlv-saving,
.xlv-clue-label {
  font-variant-numeric: tabular-nums;
}

:root {
  --xlvm-bg: #f6f6f4;
  --xlvm-surface: #ffffff;
  --xlvm-text: #1a1a1a;
  --xlvm-muted: #5f5f5f;
  --xlvm-accent: #2a5d8f;
  --xlvm-border: #dcdcd6;
  --xlvm-radius: 10px;
}

/* ---------------------------------------------------------------------------
 * Site header.
 *
 * CRITICAL: hidden entirely on phones. Exolve only enables its phone mode
 * (on-screen keyboard, sticky clue, header rearrangement) when
 * `frame.offsetTop <= 16` — see exolve-m.js:1463. Any header in normal flow
 * above the puzzle pushes the frame down and disables all of it silently.
 *
 * On desktop the header is harmless because Exolve's phone mode bails out
 * above a 500px viewport regardless. So: normal flow above 500px, gone below.
 * The visTop measurement in puzzle.html.j2 reads 0 for a display:none element,
 * which is exactly what we want.
 * ------------------------------------------------------------------------ */
.xlvm-site-header {
  display: none;
}

@media (min-width: 501px) {
  .xlvm-site-header {
    display: block;
    padding: 10px 0 14px 0;
    font-family: "InterVariable", system-ui, -apple-system, "Segoe UI", sans-serif;
    font-size: 14px;
  }
}

.xlvm-site-home {
  color: var(--xlvm-accent);
  text-decoration: none;
}

.xlvm-site-home:hover {
  text-decoration: underline;
}

/* ---------------------------------------------------------------------------
 * Site footer. In normal flow below the puzzle, so it is safe on all sizes
 * and carries the navigation that the header would otherwise provide on a
 * phone. The browser back button covers the rest.
 * ------------------------------------------------------------------------ */
.xlvm-site-footer {
  margin: 28px 0 0 0;
  padding: 14px 0 calc(14px + env(safe-area-inset-bottom)) 0;
  border-top: 1px solid var(--xlvm-border);
  font-family: "InterVariable", system-ui, -apple-system, "Segoe UI", sans-serif;
  font-size: 13px;
  color: var(--xlvm-muted);
  text-align: center;
}

.xlvm-site-footer a {
  color: var(--xlvm-accent);
  text-decoration: none;
  /* Comfortable tap target without changing the line box. */
  display: inline-block;
  padding: 6px 2px;
}

.xlvm-site-footer a:hover {
  text-decoration: underline;
}

.xlvm-sep {
  margin: 0 6px;
  opacity: 0.6;
}

/* ---------------------------------------------------------------------------
 * Index page.
 *
 * Standalone: Exolve's stylesheet is not loaded here, so everything the index
 * needs is defined in this block.
 * ------------------------------------------------------------------------ */
body.xlvm-index {
  margin: 0 auto;
  padding: 24px max(16px, env(safe-area-inset-left))
           max(16px, env(safe-area-inset-bottom))
           max(16px, env(safe-area-inset-right));
  max-width: 42rem;
  background: var(--xlvm-bg);
  color: var(--xlvm-text);
  font-family: "InterVariable", system-ui, -apple-system, "Segoe UI", sans-serif;
  line-height: 1.5;
  -webkit-text-size-adjust: 100%;
}

.xlvm-index-header h1 {
  margin: 0 0 4px 0;
  font-size: 1.7rem;
  letter-spacing: -0.01em;
}

.xlvm-tagline {
  margin: 0 0 24px 0;
  color: var(--xlvm-muted);
  font-size: 0.95rem;
}

.xlvm-puzzle-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.xlvm-puzzle-link {
  /* Whole card is the tap target, comfortably over the 44px minimum. */
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 14px 16px;
  background: var(--xlvm-surface);
  border: 1px solid var(--xlvm-border);
  border-radius: var(--xlvm-radius);
  color: inherit;
  text-decoration: none;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
  transition: border-color 0.15s ease, transform 0.15s ease;
}

.xlvm-puzzle-link:hover,
.xlvm-puzzle-link:focus-visible {
  border-color: var(--xlvm-accent);
}

.xlvm-puzzle-link:active {
  transform: scale(0.995);
}

.xlvm-puzzle-title {
  font-size: 1.05rem;
  font-weight: 600;
}

.xlvm-puzzle-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  font-size: 0.85rem;
  color: var(--xlvm-muted);
}

.xlvm-setter::after {
  content: "\00b7";
  margin-left: 8px;
  opacity: 0.6;
}

.xlvm-empty {
  padding: 32px 0;
  color: var(--xlvm-muted);
  text-align: center;
}

@media (prefers-reduced-motion: reduce) {
  .xlvm-puzzle-link {
    transition: none;
  }

  .xlvm-puzzle-link:active {
    transform: none;
  }
}
