/* ════════════════════════════════════════════════════════
   THE GRAMMAR MAP
   Companion styles for grammar-map.js.

   A flat run of independent tables, each on its own faint card,
   in the fixed order set by LAYOUT in grammar-map.js. Every cell
   is a stack of slots, and a slot is a tag plus a body carrying
   one of four states:

     is-new    teal   — taught in this lesson
     is-known  gold   — taught in an earlier lesson
     is-dim    ruled  — still ahead; the tag shows, the word does not
     is-void   struck — a slot German does not have at all

   All colour comes from tokens.css, so the map follows the
   light / dark / paper / wald themes without extra work.
   ════════════════════════════════════════════════════════ */

.gm {
  max-width: var(--max-width);
  margin: var(--section-gap) auto;
  padding: 0 var(--page-pad-x);
  font-family: var(--sans);
}

/* ── The card ─────────────────────────────────────────────
   Every table sits on its own faint field with room around it.
   They are independent: no table is welded to the one above it,
   and nothing groups them. */

.gm-table-wrap {
  background: var(--card-bg);
  border-radius: 12px;
  padding: 26px 28px 28px;
  margin: 0 0 14px;
}

.gm-table-wrap.is-narrow { max-width: 340px; }

.gm-table-title {
  font-size: var(--size-base);
  font-weight: 800;
  color: var(--ink);
  margin: 0;
  line-height: 1.25;
}

/* Arriving from a lesson tab. The card says "here" for a moment
   and then stops, because the student came to read, not to be
   pointed at. */
.gm-table-wrap.is-arrived {
  box-shadow: 0 0 0 2px var(--correct-border);
  transition: box-shadow 900ms ease;
}

/* ── The table ────────────────────────────────────────── */

/* Wide tables scroll inside their own box; the page never
   scrolls sideways. */
.gm-scroll {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  margin-top: 10px;
}

.gm-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.9rem;
}

.gm-corner,
.gm-colhead {
  font-size: 0.64rem;
  font-weight: 700;
  letter-spacing: var(--track-label-tight);
  text-transform: uppercase;
  color: var(--ink-mid);
  text-align: left;
  padding: 0 12px 8px 0;
  white-space: nowrap;
  border-bottom: 1.5px solid var(--divider);
}

.gm-corner { padding-left: 0; }

.gm-rowhead {
  text-align: left;
  vertical-align: top;
  padding: 10px 16px 10px 0;
  white-space: nowrap;
  border-bottom: 1px solid var(--divider);
}

.gm-rowhead.is-empty { padding: 0; width: 0; }

.gm-rowhead-label {
  display: block;
  font-size: 0.82rem;
  font-weight: 700;
  color: var(--ink);
  line-height: 1.25;
}

.gm-rowhead-gloss {
  display: block;
  font-size: 0.66rem;
  font-weight: 400;
  color: var(--ink-faint);
  line-height: 1.3;
}

.gm-td {
  padding: 10px 14px 10px 0;
  vertical-align: top;
  border-bottom: 1px solid var(--divider);
  font-weight: 600;
  white-space: nowrap;
}

.gm-td.is-empty { border-bottom: 1px solid var(--divider); }
.gm-td.is-stack { line-height: 1.5; }

/* er, sie and es share one verb form, so those tables merge them.
   The merged cell keeps its text at the top so it still reads
   level with the row it belongs to. */
.gm-td[rowspan],
.gm-rowhead[rowspan] { vertical-align: top; }

/* ── A slot ───────────────────────────────────────────────
   A slot is a tag and a body. The tag names what belongs there and
   is always visible; the body is the German form once it is taught,
   and a ruled line while it is still ahead. Naming the slot costs
   the learner nothing, because the tag is English and the thing
   being withheld is the German word.

   Every slot is the same box whether it holds a word or a rule, so
   a half-full cell still reads level with the cell beside it.
   Reading across is the whole point of the table. */

.gm-line {
  display: flex;
  align-items: baseline;
  gap: 8px;
  padding: 5px 9px;
  margin-bottom: 6px;
  border-radius: 4px;
  background: var(--card-bg-deep);
  transition: box-shadow var(--dur-fast) ease;
}

.gm-line:last-child { margin-bottom: 0; }
.gm-line:hover { box-shadow: inset 0 0 0 1px var(--divider); }

.gm-line-tag {
  flex: none;
  min-width: 3.2em;
  font-size: 0.66rem;
  font-weight: 600;
  letter-spacing: var(--track-label-tight);
  color: var(--ink-mid);
  opacity: 0.72;
  white-space: nowrap;
}

.gm-line-word {
  flex: 1 1 auto;
  white-space: nowrap;
}

/* Still ahead: a line waiting to be filled. */
.gm-line-rule {
  flex: 1 1 auto;
  align-self: center;
  min-width: 2.4em;
  height: 1.5px;
  border-radius: 1px;
  background: var(--divider);
}

.gm-line.is-known .gm-line-word { color: var(--german); }
.gm-line.is-new   { background: var(--correct-bg); }
.gm-line.is-new   .gm-line-word { color: var(--correct-ink); font-weight: 800; }
.gm-line.is-new   .gm-line-tag  { opacity: 0.9; }

/* A slot German genuinely does not have. Cancelled rather than
   pending, so nobody waits for a light that is never coming. */
.gm-line.is-void { opacity: 0.45; }
.gm-line.is-void .gm-line-tag  { text-decoration: line-through; }
.gm-line.is-void .gm-line-rule { background: var(--ink-faint); }

/* In the ein-word table the last slot is the bare ending, the thing
   all four words above it have in common. Set apart by a gap, not
   shouted. Scoped to that table: everywhere else the last slot is
   just another form. */
#gm-t-einwords .gm-td .gm-line:last-child {
  margin-top: 7px;
}

/* ── The tab on the lesson page ───────────────────────
   An edge tab, on the same side as the continue button and built
   to the same rule: flush to the bezel, rounded on the inside,
   the width of its neighbour. Two controls on one edge read as a
   pair; one on each edge read as clutter.

   It sits ABOVE the continue button rather than at mid-height,
   because on desktop the dot nav still owns the right edge at
   vertical centre. Stacking is what keeps all three clear of each
   other, so the offsets below are the continue button's own
   bottom and height plus a gap — change one and this follows. */

.gm-tab {
  position: fixed;
  /* Mirrors .l-continue-btn: bottom 40px, height 50px, then a gap. */
  right: 0;
  bottom: 102px;
  z-index: var(--z-panel);
  transition: transform var(--dur-base) ease;
}

/* Inward, away from the edge it is anchored to. The old tab moved
   right because it hung off the left. */
.gm-tab:hover { transform: translateX(-4px); }

.gm-tab-link {
  display: flex;
  align-items: center;
  justify-content: center;
  /* Not rotated at all. It ran bottom-to-top when it hung off the left
     edge, and top-to-bottom after it moved right; both make you tilt
     your head, just in opposite directions. Set horizontally over two
     lines it simply reads, and at this width "The Map" breaks at its
     own space with no help.

     It also lands the tab at roughly 54x55, against the continue
     button's 54x50 — so the pair reads as two tabs of a size rather
     than a strip above a key. */
  width: 54px;
  padding: 14px 4px;
  text-align: center;
  line-height: 1.25;
  /* Letter-spacing adds a trailing gap after the last letter, which
     drags centred text left by half of it. */
  text-indent: 0.1em;
  border-radius: var(--radius-pill) 0 0 var(--radius-pill);
  /* card-bg-deep rather than card-bg: on the wald theme the shallower
     card colour sits too close to the page green and the tab all but
     disappears. */
  background: var(--card-bg-deep);
  border: 1px solid var(--divider);
  border-right: none;
  /* Cast inward, matching the continue button's -3px 3px. */
  box-shadow: -2px 2px 12px rgba(0, 0, 0, 0.14);
  color: var(--ink);
  text-decoration: none;
  font-size: 0.68rem;
  font-weight: 800;
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  transition: background var(--dur-base) ease, color 180ms ease;
}

.gm-tab-link:hover {
  background: var(--gold);
  color: #211508;
}

/* Below 1280px the lesson column runs right up to the page padding,
   which is 28px. The tab stays a tab, narrowed to sit inside that
   margin rather than on top of the words. */
/* Touch layout, tracking .l-continue-btn exactly: it grows to 62x58
   and clears the home indicator, so the tab grows and lifts with it.
   The safe-area inset has to appear here too — without it the pair
   drifts apart on an iPhone, which is the one place they are most
   obviously side by side. */
@media (max-width: 899px) {
  .gm-tab {
    /* The chevron sits at 36px with 58px of height, so its top edge is
       at 94px. 118px leaves 24px of clear air between them — at 12px
       they read as one stuck-together control. */
    bottom: calc(118px + env(safe-area-inset-bottom));
  }
  /* Back to one straight vertical line here, turned 90 degrees.
     The two-line horizontal label works on a desktop, where the tab
     can be wide without crowding anything; at phone width the same
     box looks bolted onto the edge. A single line is narrower, and
     the tab reads as a tab again. */
  .gm-tab-link {
    writing-mode: vertical-rl;
    white-space: nowrap;
    /* A little wider than the chevron's 62px, so the pair reads as
       deliberate rather than as two things that nearly line up. */
    width: 66px;
    padding: 20px 0;
    text-indent: 0;
    font-size: 0.62rem;
    letter-spacing: var(--track-label);
    box-shadow: -3px 3px 18px rgba(0, 0, 0, 0.22);
  }
}

/* ── Back to the lesson ───────────────────────────────── */

.gm-back {
  font-size: var(--size-sm);
  font-weight: 700;
  color: var(--ink);
  text-decoration: none;
  white-space: nowrap;
}

.gm-back:hover { color: var(--german); }

/* ── Standalone page ──────────────────────────────────── */

.gm-scrub {
  position: sticky;
  top: 0;
  z-index: 20;
  background: var(--bg);
  border-bottom: 1px solid var(--divider);
  padding: 14px var(--page-pad-x);
}

.gm-scrub-inner {
  max-width: var(--max-width);
  margin: 0 auto;
  display: flex;
  align-items: center;
  gap: 14px;
}

.gm-scrub-label {
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: var(--track-label-tight);
  text-transform: uppercase;
  color: var(--ink-mid);
  white-space: nowrap;
  min-width: 82px;
}

.gm-scrub input[type="range"] {
  flex: 1;
  accent-color: var(--gold);
}

/* ── Small screens ────────────────────────────────────── */

@media (max-width: 560px) {
  .gm-table { font-size: 0.82rem; }
  .gm-td { padding-right: 11px; }
  .gm-rowhead { padding-right: 12px; }
  .gm-rowhead-gloss { display: none; }
  .gm-table-wrap { padding: 18px 16px 20px; border-radius: 10px; }
}
