/* ============================================================================
   learningjourney.work — Crouwel gridded type specimen (see ../DESIGN.md).
   The construction grid is visible and IS the design. Ink + one blue. Cells.
   ========================================================================== */

:root {
  --paper: #ffffff;
  --surface: #f5f7fa;
  --ink: #111111;
  --ink-soft: #3d4148;      /* secondary text — still ≥7:1 on paper */
  --blue: #0057ff;
  --grid-line: #e6ebf2;
  /* --cell IS the ruling: 12px, the same size as one cell of the wordmark's
     letterforms and one cell of a tile icon, so drawn cells cover ruled
     squares exactly rather than floating over them at their own pitch.
     --mod is the two-cell module everything is spaced and sized by. */
  --cell: 12px;
  --mod: calc(var(--cell) * 2);
  --display: "Chakra Petch", sans-serif;
  --grotesk: "Archivo", sans-serif;
}

* { margin: 0; padding: 0; box-sizing: border-box; }

/* The UA's [hidden] rule loses to any class that sets display (.ghost-btn is
   inline-block), which left the admin's Sign out button visible while signed
   out. Make the attribute authoritative. */
[hidden] { display: none !important; }

html { scroll-behavior: smooth; }

body {
  font-family: var(--grotesk);
  font-size: 15px;
  /* Type sits ON the grid: every line box is exactly one cell tall, so text
     rows land on the ruling instead of floating over it. Everything vertical
     below is a whole or half cell for the same reason. */
  line-height: var(--mod);
  color: var(--ink);
  background-color: var(--paper);
  /* The construction grid — the world's ground, toggleable as a real state. */
  background-image:
    linear-gradient(var(--grid-line) 1px, transparent 1px),
    linear-gradient(90deg, var(--grid-line) 1px, transparent 1px);
  background-size: var(--cell) var(--cell);
  -webkit-font-smoothing: antialiased;
}
body.grid-off { background-image: none; }

/* Register the grid with the sheet: above the sheet's width, pin a line to
   viewport center (+half a cell) — 552 = 23 cells, so the 1104px sheet's
   edges land on grid lines at every viewport width. Below that, the pattern's
   0-origin already aligns with the one-cell page padding. */
@media (min-width: 1104px) {
  /* a rule exactly at viewport centre; 552 = 46 cells, so the sheet's edges
     land on rules at every width */
  body { background-position: calc(50% + 6px) 0; }
}

.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

::selection { background: var(--blue); color: #fff; }

a { color: inherit; }

:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }

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

.sheet {
  max-width: calc(var(--mod) * 46);       /* 1104px — whole cells */
  margin: 0 auto;
  padding: 0 var(--mod);
}

/* ---- top bar — /admin/ only ---------------------------------------------------
   The landing page has no chrome above the wordmark: a student arriving mid
   lesson should meet the page itself, not a nav strip. The grid toggle moved
   to the footer; the teacheng.work link was already in the footer nav. */

.bar {
  border-bottom: 1px solid var(--ink);
  background: var(--paper);
}
.bar-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--mod);
  height: calc(var(--mod) * 3);
}
.wordmark-small {
  font-family: var(--display);
  font-weight: 700;
  font-size: 15px;
  letter-spacing: 0.14em;
  text-decoration: none;
  white-space: nowrap;
}
.wordmark-small .slash { color: var(--blue); }
.bar-actions { display: flex; align-items: center; gap: calc(var(--mod) / 2); }

.ghost-btn {
  font-family: var(--display);
  font-weight: 600;
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink);
  background: var(--paper);
  border: 1px solid var(--ink);
  padding: 0 calc(var(--mod) / 2);
  min-height: calc(var(--mod) * 2);   /* two modules, past the 44px touch floor */
  min-width: calc(var(--mod) * 4);
  cursor: pointer;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.ghost-btn:hover { background: var(--ink); color: #fff; }
/* active states are blue — the board's active grammar */
.ghost-btn[aria-pressed="true"] { background: var(--blue); border-color: var(--blue); color: #fff; }
.bar-short { display: none; }

/* ---- hero ------------------------------------------------------------------ */

/* padding-block only: a `padding` shorthand here would override .sheet's
   horizontal padding and bleed the hero to the screen edge on any viewport
   narrower than the sheet (i.e. every PLD in portrait). */
.hero {
  padding-top: calc(var(--mod) * 3);
  padding-bottom: var(--mod);
}

/* 52 glyph cells wide at --cell each, so ONE GLYPH CELL IS ONE RULED CELL and
   the letterforms fill squares of the grid rather than floating over it at
   their own pitch. 16 rows tall follows from the viewBox. Left-aligned, not
   centred: the sheet is a whole number of cells only at its maximum width, so
   centring lands on a half cell everywhere else. */
.wordmark-wrap { margin: 0; font-size: 0; line-height: 0; }
.wordmark {
  display: block;
  width: min(calc(var(--cell) * 52), 100%);
  height: auto;
}
.wordmark .cell { fill: var(--ink); }
.wordmark .cell.accent { fill: var(--blue); }

.hero-actions {
  margin-top: var(--mod);
  display: flex;
  flex-wrap: wrap;
  gap: var(--mod);
  align-items: center;
}

/* ---- search: the primary control ------------------------------------------
   A student usually arrives having been told one app's name. The field is a
   specimen module (label above the box, as the type-specimen board sets its
   INPUT / TEXT rows), sized to the 44px touch floor of a school PLD. */

.search {
  /* Spans the whole sheet: the largest the field can be, centred on screen
     because the sheet is, and on the ruling at both ends at every width —
     which a fixed centred width could not be. */
  margin-top: calc(var(--mod) * 2);
}
.search-label {
  display: block;
  font-family: var(--display);
  font-weight: 600;
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  line-height: var(--mod);
  margin-bottom: calc(var(--mod) / 2);
}
.search-field {
  display: flex;
  align-items: stretch;
  /* outline, not border — see .entry: a border sits inside the box and pushes
     what follows it half a cell off the ruling */
  border: 0;
  outline: 1px solid var(--ink);
  outline-offset: -1px;
  background: var(--paper);
  height: calc(var(--mod) * 3);
}
/* Below its maximum the sheet is a fluid width, so its right edge falls
   between rules. Round the field down to the last whole cell so its own right
   edge — and the CLEAR button pinned to it — land on one. */
@supports (width: round(down, 10px, 3px)) {
  .search-field { width: round(down, 100%, var(--cell)); }
}
.search-field:focus-within { outline-color: var(--blue); }
.search-mark { width: var(--mod); height: var(--mod); flex: none; align-self: center; margin-left: calc(var(--mod) / 2); }
.search-mark line { stroke: var(--blue); stroke-width: 2; }
.search-input {
  flex: 1;
  min-width: 0;
  height: 100%;
  border: 0;
  background: transparent;
  padding: 0 calc(var(--mod) / 2);
  font-family: var(--grotesk);
  font-size: 20px;           /* >=16px also stops iOS zooming the page on focus */
  color: var(--ink);
}
.search-input:focus { outline: none; }
.search-input::placeholder { color: var(--ink-soft); opacity: 1; }
.search-input::-webkit-search-cancel-button { display: none; }
.search-clear {
  font-family: var(--display);
  font-weight: 600;
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  border: 0;
  border-left: 1px solid var(--ink);
  background: var(--paper);
  color: var(--ink);
  width: calc(var(--mod) * 4);
  flex: none;
  padding: 0;
  height: 100%;
  cursor: pointer;
}
.search-clear:hover { background: var(--ink); color: #fff; }

.section-action { margin-left: auto; }

/* live, truthful figures — set by js/app.js from apps.json */
.hero-stats {
  font-family: var(--display);
  font-weight: 600;
  font-size: 12px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.hero-stats b { color: var(--blue); font-weight: 700; }

/* ---- buttons ---------------------------------------------------------------- */

.btn {
  font-family: var(--display);
  font-weight: 600;
  font-size: 13px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: calc(var(--mod) / 2);
  height: calc(var(--mod) * 2);
  /* A whole-cell box, not one sized by its label: 14 modules is the same
     track width as a tile and a card, so the button lines up with the
     columns beneath it and its right edge lands on a rule. */
  width: calc(var(--mod) * 14);
  max-width: 100%;
  justify-content: space-between;
  padding: 0 var(--mod);
  border: 1px solid var(--blue);
  cursor: pointer;
}
.btn .diag { display: inline-block; width: 16px; height: 16px; flex: none; }
.btn .diag line { stroke-width: 2; }

.btn-primary { background: var(--blue); color: #fff; }
.btn-primary .diag line { stroke: #fff; }
.btn-primary:hover:not(:disabled) { background: var(--ink); border-color: var(--ink); }
.btn:disabled { opacity: 0.35; cursor: default; }

.btn-secondary { background: var(--paper); color: var(--ink); border-color: var(--ink); }
.btn-secondary .diag line { stroke: var(--blue); }
.btn-secondary:hover { border-color: var(--blue); color: var(--blue); }

/* ---- directory -------------------------------------------------------------- */

.directory { padding-bottom: calc(var(--mod) * 3); }

/* ---- section tiles — the page's navigation ---------------------------------
   One shaded box per section, naming what you are trying to do. Pressing one
   opens that section below; a search opens whichever sections its results
   land in. Icons are drawn from the same 4px sub-cells as the wordmark. */

.tiles {
  display: grid;
  /* Small enough that all six sit on ONE line, so opening and closing a
     section barely moves the page. 13-cell tracks with a 2-cell gutter make
     6 * 13 + 5 * 2 = 88 cells, which is the sheet exactly. Fixed tracks, not
     `1fr`, so every column still starts on a rule. */
  grid-template-columns: repeat(auto-fill, calc(var(--cell) * 13));
  gap: calc(var(--cell) * 2);
  justify-content: start;
  margin-top: var(--mod);
}
.tile {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--cell);
  height: calc(var(--cell) * 10);  /* whole cells, so the row sits on the ruling */
  padding: var(--cell);
  /* No card. The section IS a shaded block of the grid: the ruling carries on
     through it, drawn at the same pitch and phase as the page's, because the
     tile's own corner sits on a rule. */
  border: 0;
  background-color: var(--surface);
  background-image:
    linear-gradient(var(--grid-line) 1px, transparent 1px),
    linear-gradient(90deg, var(--grid-line) 1px, transparent 1px);
  background-size: var(--cell) var(--cell);
  color: var(--ink);
  text-align: left;
  cursor: pointer;
  font: inherit;
  position: relative;
  overflow: hidden;
}
.tile > * { position: relative; z-index: 1; }
.tile:hover:not(:disabled) { background-color: #eaeef5; }

/* Opening a tile fills it in cell by cell along the diagonal. The blue is a
   real child element, not a pseudo-element, so js can drive its clip-path
   staircase; it is per-element, so choosing one tile animates that tile and
   touches no other. */
.tile-fill {
  /* Clipped to nothing until js fills it in. Without this the layer covers
     its tile and every category renders solid blue. */
  clip-path: polygon(0% 0%, 0% 0%, 0% 0%);
  position: absolute;
  inset: 0;
  z-index: 0;
  background-color: var(--blue);
  background-image:
    linear-gradient(rgba(255,255,255,.22) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255,255,255,.22) 1px, transparent 1px);
  background-size: var(--cell) var(--cell);
}

/* the label waits for the fill to reach it, then flips; closing flips back at
   once, because the blue is leaving from under it */
.tile[aria-expanded="true"] { color: #fff; transition: color 0ms 260ms; }
/* the icon sits at the far left, so the wipe covers it within its first two
   steps — flip it then, or it is blue on blue and disappears mid-fill */
.tile[aria-expanded="true"] .tile-icon { fill: #fff; transition: fill 0ms 60ms; }
.tile[aria-expanded="true"] .tile-count { color: rgba(255, 255, 255, 0.85); transition: color 0ms 260ms; }
.tile:disabled { opacity: 0.4; cursor: default; }

.tile-icon { width: calc(var(--cell) * 3); height: calc(var(--cell) * 3); flex: none; fill: var(--blue); }

.tile-name {
  font-family: var(--display);
  font-weight: 600;
  font-size: 10px;
  line-height: var(--cell);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.tile-count {
  margin-top: auto;
  font-family: var(--display);
  font-size: 10px;
  line-height: var(--cell);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

.section { margin-top: calc(var(--mod) * 2); }
.section-head {
  display: flex;
  align-items: baseline;
  gap: calc(var(--mod) / 2);
  border-bottom: 1px solid var(--ink);
  height: calc(var(--mod) * 2);
}
.section-index {
  font-family: var(--display);
  font-weight: 700;
  font-size: 13px;
  color: var(--blue);
  letter-spacing: 0.08em;
}
.section-title {
  font-family: var(--display);
  font-weight: 600;
  font-size: 17px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}
.section-count {
  margin-left: auto;
  font-family: var(--display);
  font-size: 11px;
  letter-spacing: 0.1em;
  color: var(--ink-soft);
}

.entries {
  display: grid;
  /* Whole-cell tracks, packed from the left — same reasoning as .tiles. */
  grid-template-columns: repeat(auto-fill, calc(var(--mod) * 14));
  justify-content: start;
  gap: var(--mod);
  margin-top: var(--mod);
}

.entry {
  display: flex;
  flex-direction: column;
  /* Same object as a tile, so the same treatment: not a card with a rule round
     it but a region of the grid filled in, with the ruling carrying straight
     through at the page's own pitch and phase. */
  border: 0;
  background-color: var(--surface);
  background-image:
    linear-gradient(var(--grid-line) 1px, transparent 1px),
    linear-gradient(90deg, var(--grid-line) 1px, transparent 1px);
  background-size: var(--cell) var(--cell);
  color: var(--ink);
  text-decoration: none;
  height: calc(var(--mod) * 11);   /* 22 ruled cells */
  padding: var(--mod);
  overflow: hidden;
}
.entry-body { padding: 0; }
.entry-code {
  display: inline-block;
  font-family: var(--display);
  font-weight: 700;
  font-size: 11px;
  letter-spacing: 0.14em;
  color: var(--blue);
  border: 1px solid var(--blue);
  height: var(--mod);
  line-height: calc(var(--mod) - 2px);
  padding: 0 calc(var(--mod) / 2);
  text-align: center;
  overflow: hidden;
}
.entry-title {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  font-family: var(--display);
  font-weight: 600;
  font-size: 19px;
  line-height: var(--mod);
  letter-spacing: 0.02em;
  text-transform: uppercase;
  margin-top: calc(var(--mod) / 2);
}
.entry-desc {
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
  margin-top: calc(var(--mod) / 2);
  color: var(--ink-soft);
  font-size: 14px;
}
.entry-foot {
  margin-top: auto;
  height: var(--mod);
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-family: var(--display);
  font-weight: 600;
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}
.entry-foot .diag { width: 14px; height: 14px; transform: translate(-6px, 6px); }
.entry-foot .diag line { stroke: var(--blue); stroke-width: 2; }
.entry:hover .entry-foot .diag, .entry:focus-visible .entry-foot .diag { transform: translate(0, 0); }

.entry:hover, .entry:focus-visible {
  background-color: var(--blue);
  background-image:
    linear-gradient(rgba(255,255,255,.22) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255,255,255,.22) 1px, transparent 1px);
  color: #fff;
}
.entry:hover .entry-code, .entry:focus-visible .entry-code { color: #fff; border-color: #fff; }
.entry:hover .entry-desc, .entry:focus-visible .entry-desc { color: rgba(255,255,255,.88); }
.entry:hover .entry-foot .diag line, .entry:focus-visible .entry-foot .diag line { stroke: #fff; }

/* external (Telegram) entries note their leaving in the footer */
.entry-foot .ext { font-size: 10px; letter-spacing: 0.1em; color: var(--ink-soft); }
.entry:hover .entry-foot .ext, .entry:focus-visible .entry-foot .ext { color: rgba(255,255,255,.88); }

/* ---- empty / offline state -------------------------------------------------- */

.empty {
  margin-top: calc(var(--mod) * 2);
  border: 1px solid var(--ink);
  padding: calc(var(--mod) * 2);
  background-image: radial-gradient(var(--grid-line) 1.5px, transparent 1.5px);
  background-size: calc(var(--mod) / 2) calc(var(--mod) / 2);
}
.empty h2 {
  font-family: var(--display);
  font-weight: 600;
  font-size: 19px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}
.empty p { margin-top: calc(var(--mod) / 2); color: var(--ink-soft); max-width: 58ch; }
.empty .btn { margin-top: var(--mod); }

/* ---- footer ------------------------------------------------------------------ */

.foot {
  border-top: 1px solid var(--ink);
  /* the rule is 1px inside the box, so take it back off the padding or every
     child below sits one pixel off the ruling */
  padding: calc(var(--mod) * 1.5 - 1px) 0 calc(var(--mod) * 2);
}
.foot-inner {
  display: flex;
  flex-wrap: wrap;
  gap: var(--mod);
  align-items: center;
  justify-content: space-between;
}
.foot p { color: var(--ink-soft); font-size: 13px; }
.foot nav { display: flex; flex-wrap: wrap; gap: var(--mod); }
.foot a {
  font-family: var(--display);
  font-weight: 600;
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  text-decoration: none;
  border-bottom: 1px solid var(--blue);
  padding-bottom: 2px;
}
.foot a:hover { color: var(--blue); }

/* ============================================================================
   /admin/ — the paste-up sheet. Same world, Operate register.
   ========================================================================== */

/* padding-block only — same reason as .hero above */
.admin-main { padding-top: calc(var(--mod) * 2); padding-bottom: calc(var(--mod) * 6); }

.panel {
  border: 1px solid var(--ink);
  background: var(--paper);
  padding: var(--mod);
  margin-top: var(--mod);
}
.panel-title {
  font-family: var(--display);
  font-weight: 600;
  font-size: 13px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  display: flex;
  align-items: baseline;
  gap: calc(var(--mod) / 2);
}
.panel-title .section-index { font-size: 12px; }
.panel-note { margin-top: calc(var(--mod) / 2); color: var(--ink-soft); font-size: 13px; max-width: 68ch; }

.auth-row { margin-top: var(--mod); display: flex; align-items: center; gap: var(--mod); flex-wrap: wrap; }
.auth-who { font-size: 13px; color: var(--ink-soft); }
.auth-who b { color: var(--ink); }

.problem {
  margin-top: var(--mod);
  border: 2px solid var(--ink);
  padding: calc(var(--mod) / 2) var(--mod);
  font-size: 14px;
}
.problem b { font-family: var(--display); letter-spacing: 0.08em; text-transform: uppercase; font-size: 12px; }

/* rows */
.row-list { margin-top: var(--mod); display: flex; flex-direction: column; gap: calc(var(--mod) / 2); }

.row {
  display: flex;
  align-items: center;
  gap: calc(var(--mod) / 2);
  border: 1px solid var(--ink);
  background: var(--paper);
  padding: calc(var(--mod) / 2) calc(var(--mod) / 2);
}
.row.hidden-row {
  border-style: dashed;
  background-image: radial-gradient(var(--grid-line) 1.5px, transparent 1.5px);
  background-size: calc(var(--mod) / 2) calc(var(--mod) / 2);
}
.row.hidden-row .row-title { color: var(--ink-soft); }

.row-pos {
  font-family: var(--display);
  font-weight: 700;
  font-size: 12px;
  color: var(--blue);
  min-width: 2.2em;
}
.row-code {
  font-family: var(--display);
  font-weight: 700;
  font-size: 10px;
  letter-spacing: 0.12em;
  color: var(--blue);
  border: 1px solid var(--blue);
  padding: 0 calc(var(--mod) / 4);
  line-height: calc(var(--mod) - 2px);
  white-space: nowrap;
}
.hidden-row .row-code { color: var(--ink-soft); border-color: var(--ink-soft); }
.row-main { flex: 1; min-width: 0; }
.row-title {
  font-family: var(--display);
  font-weight: 600;
  font-size: 14px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.row-cat { font-size: 12px; color: var(--ink-soft); }
.row-controls { display: flex; gap: calc(var(--mod) / 4); flex: none; }

.ctl {
  font-family: var(--display);
  font-weight: 600;
  font-size: 11px;
  letter-spacing: 0.08em;
  min-width: var(--mod);
  height: calc(var(--mod) * 2);
  padding: 0 10px;
  background: var(--paper);
  border: 1px solid var(--ink);
  cursor: pointer;
  color: var(--ink);
}
.ctl svg { width: 14px; height: 14px; display: block; margin: 0 auto; }
.ctl svg line { stroke: currentColor; stroke-width: 2; }
.ctl:hover:not(:disabled) { background: var(--ink); color: #fff; }
.ctl:disabled { opacity: 0.35; cursor: default; }
.ctl-show { border-color: var(--blue); color: var(--blue); }
.ctl-show:hover:not(:disabled) { background: var(--blue); color: #fff; }

/* save bar */
.savebar {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  background: var(--paper);
  border-top: 1px solid var(--ink);
}
.savebar-inner {
  display: flex;
  align-items: center;
  gap: var(--mod);
  padding: calc(var(--mod) / 2) 0;
  padding-bottom: calc(var(--mod) / 2 + env(safe-area-inset-bottom, 0px));
}
.dirty-flag {
  font-family: var(--display);
  font-weight: 700;
  font-size: 11px;
  letter-spacing: 0.14em;
  color: var(--blue);
  border: 1px solid var(--blue);
  padding: 4px 10px;
  visibility: hidden;
}
.dirty-flag.on { visibility: visible; }
.save-status { font-size: 13px; color: var(--ink-soft); margin-left: auto; }

/* ---- motion: things arrive by filling in, cell by cell ----------------------
   The wordmark assembles a cell at a time; tiles, their icons and the cards
   do the same, wiping in on the cell pitch with steps() so nothing ever slides
   between two cells. Staggers come from --d, set per element in js. */




/* ---- motion: cell snaps only ------------------------------------------------ */

.entry, .entry-foot, .entry-foot .diag, .entry-foot .diag line, .btn, .ghost-btn, .ctl, .foot a {
  transition: background-color 140ms ease-out, color 140ms ease-out,
              border-color 140ms ease-out, stroke 140ms ease-out,
              transform 140ms ease-out;
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { transition: none !important; animation: none !important; }
}

/* ---- small screens: reflow by whole cells -----------------------------------
   The primary device is a school PLD, not a phone: ~768-834px in portrait,
   ~1024-1366px in landscape. Portrait falls here, so the hero has to compress
   or a student in class scrolls past a full screen of wordmark to reach the
   apps. Phones inherit the same rules and then narrow further at 720px. */

@media (max-width: 900px) {
  .hero { padding-top: calc(var(--mod) * 2); padding-bottom: var(--mod); }
  .wordmark { max-width: calc(var(--mod) * 28); }
  .hero-actions { margin-top: var(--mod); }
}

@media (max-width: 720px) {
  :root { --cell: 10px; }
  .bar-inner { height: calc(var(--mod) * 3); }
  .entries, .tiles { grid-template-columns: 1fr; }
  .row { flex-wrap: wrap; }
  .row-main { flex-basis: 100%; order: 3; }
  .savebar-inner { flex-wrap: wrap; gap: calc(var(--mod) / 2); }
  .save-status { margin-left: 0; flex-basis: 100%; }
}

/* narrow phones: the top bar must never overflow — drop the duplicate site
   link (it lives in the footer) and use the short bar title */
@media (max-width: 520px) {
  .bar-long { display: none; }
  .bar-short { display: inline; }
}
