/*
 * Grammar Exercises - the styles that only these pages need.
 *
 * Everything structural comes from notebook.css: the paper, the wrap, .card, .btn, .chip, the
 * fonts and the whole colour scale. This file adds the exercise itself and nothing else, so a
 * change to the site's look still reaches these pages without being re-done here.
 *
 * THE ONE RULE FOR THIS FILE: the page must read correctly with no JavaScript at all. Every
 * question is in the HTML as a sentence with visible blanks, because a crawler and a reader
 * with scripts blocked both need to see the real exercise - that is the entire argument for
 * these pages existing. So nothing here may hide a question, and the styles that belong to the
 * interactive version are scoped under .g-live, a class assets/grammar.js adds to <body> only
 * once it has successfully booted. Until then, and forever if the script fails, the static
 * version is what shows.
 */

/*
 * hidden has to actually hide.
 *
 * `[hidden]` is a user-agent rule, so any class that sets display beats it - and .btn in
 * notebook.css sets display:inline-flex. The effect was a live bug in both directions: a reader
 * with JavaScript off saw a "Check my answers" button that did nothing, and after scoring, the
 * button stayed on screen still reading "Checking...", because grammar.js sets .hidden = true
 * and nothing happened.
 *
 * !important rather than out-specifying .btn, because this has to hold for every element in
 * these pages that is hidden until the player needs it - the button, the score card and the
 * best-score line - and not silently break the next one somebody adds.
 */
[hidden] { display: none !important; }

/* ---------- the question list ---------- */

.g-qs { list-style: none; margin: 0; padding: 0; counter-reset: gq; }

.g-q {
  counter-increment: gq;
  position: relative;
  padding: 16px 18px 16px 52px;
  border-bottom: 1px dashed var(--line);
}
.g-q:last-child { border-bottom: 0; }

.g-q::before {
  content: counter(gq);
  position: absolute;
  left: 14px; top: 16px;
  width: 26px; height: 26px;
  display: flex; align-items: center; justify-content: center;
  font-family: var(--hand); font-weight: 700; font-size: 15px;
  color: var(--mut);
  border: 2px solid var(--line); border-radius: 999px;
}

.g-text { font-size: 17px; line-height: 1.85; margin: 0; }

/* The blank as it appears with no JavaScript: visible, and obviously a gap to fill. */
.g-blank { font-weight: 700; letter-spacing: 1px; color: var(--mut); }

.g-hint { font-size: 14px; color: var(--mut); margin: 6px 0 0; }

/* The verb or noun cue the sentence carries in brackets. */
.g-cue { font-style: italic; color: var(--blue); }

/* ---------- options and tiles ---------- */

.g-opts { list-style: none; display: flex; flex-wrap: wrap; gap: 8px; margin: 10px 0 0; padding: 0; }
.g-opts li { margin: 0; }

.g-opt {
  font-family: var(--read); font-size: 15px; text-align: left;
  border: 2px solid var(--line); border-radius: 10px;
  background: #fff; color: var(--ink);
  padding: 8px 14px; cursor: pointer;
}
.g-opt:hover { border-color: var(--ink); }
.g-opt[aria-pressed="true"] { border-color: var(--blue); background: #F2F6FF; font-weight: 600; }

.g-tiles { display: flex; flex-wrap: wrap; gap: 8px; margin: 10px 0 0; }
.g-tile {
  font-family: var(--read); font-size: 15px;
  border: 2px solid var(--line); border-radius: 8px; background: #fff;
  padding: 6px 12px; cursor: pointer;
}
.g-tile:hover { border-color: var(--ink); }
.g-tile[disabled] { opacity: .35; cursor: default; }

/* ---------- the live inputs ---------- */

/*
 * A short box for a gap-fill and a wide one for a whole rewritten sentence. A full-width box
 * for a one-word blank reads as a form; a short box inside a sentence reads as a gap in the
 * sentence, which is what it is. The width is fixed per type and never derived from the answer.
 */
.g-in {
  font-family: var(--read); font-size: 17px; line-height: 1.4;
  border: 0; border-bottom: 2px solid var(--blue);
  background: transparent; color: var(--ink);
  padding: 1px 4px; min-width: 80px;
  text-align: center;
}
.g-in:focus { outline: 2px solid var(--blue); outline-offset: 3px; border-radius: 3px; }
.g-in.wide { text-align: left; width: 100%; max-width: 520px; }

.g-in.ok   { border-bottom-color: var(--green); color: var(--green-d); font-weight: 600; }
.g-in.bad  { border-bottom-color: var(--red);   color: var(--red); }

/* The verdict that appears beside a checked question. */
.g-mark { font-family: var(--hand); font-weight: 700; font-size: 15px; margin-left: 8px; }
.g-mark.ok  { color: var(--green-d); }
.g-mark.bad { color: var(--red); }

.g-why {
  margin: 10px 0 0; padding: 10px 14px;
  border-left: 3px solid var(--hl);
  background: #FFFBEA;
  font-size: 15px; line-height: 1.65;
  border-radius: 0 8px 8px 0;
}
.g-why b { font-weight: 700; }

.g-q.done { background: #FCFDFF; }

/* ---------- one question at a time ---------- */

/*
 * The live view. Twenty questions are in the page for the crawler and for a reader with no
 * JavaScript; once the player boots, only the current one is on screen, because the explanation
 * has to arrive immediately after the mistake rather than in a wall of red at the end.
 *
 * Hidden, never removed - `g-all` puts the whole list back for "See all questions" and for the
 * review pass after scoring, with no re-rendering and no second source of truth.
 */
body.g-live .g-q { display: none; }
body.g-live .g-q.current { display: block; border-bottom: 0; padding: 14px 4px 4px; }
body.g-live.g-all .g-q { display: block; }
body.g-live.g-all .g-q.current { border-bottom: 1px dashed var(--line); }

/*
 * The numbered badge is dropped while one question is on screen, and comes back for the full
 * list. It has to be: a CSS counter does not increment over display:none elements, so with only
 * question 8 visible the badge read "1" while the header above it said "Question 8 of 20".
 * In the all-questions view every item is visible, so the counter is correct again.
 */
body.g-live:not(.g-all) .g-q::before { display: none; }
body.g-live:not(.g-all) .g-q { padding-left: 4px; }

/*
 * No min-height on the exercise card, and that is a decision rather than an omission.
 *
 * A floor was the obvious way to stop the page reflowing between a short question and a tall
 * feedback panel. It did not work: the verdict appears ABOVE the controls, so the buttons move
 * whatever the card's height is. All the floor bought was 200px of empty paper under the
 * controls on every question - a worse problem than the one it was solving.
 */

/* The jump link from the top of the page must not land the section under the sticky header. */
[data-grammar-exercise] { scroll-margin-top: 84px; }

/* The counter and progress bar sit above the question. */
.g-step { font-family: var(--hand); font-weight: 700; font-size: 17px; color: var(--mut); margin: 0 0 8px; }
body.g-live.g-all .g-step, body.g-live.g-all .g-track { opacity: .45; }

.g-track { height: 6px; border-radius: 999px; background: var(--line); overflow: hidden; margin-bottom: 6px; }
.g-fill { height: 100%; width: 0; background: var(--blue); border-radius: 999px; transition: width .25s ease; }

/*
 * The verdict box. Green and red rather than a neutral panel, because the single most useful
 * thing this page does is tell you instantly which of the two happened - and a learner scanning
 * back through a finished exercise needs to find the red ones without reading.
 */
.g-fb {
  margin: 14px 0 0; padding: 14px 16px;
  border-left: 4px solid var(--line); border-radius: 0 10px 10px 0;
  background: #F7F8FA;
}
.g-fb.ok  { border-left-color: var(--green); background: #F1FAF5; }
.g-fb.bad { border-left-color: var(--red);   background: #FEF3F2; }

.g-verdict { font-family: var(--hand); font-weight: 700; font-size: 19px; margin: 0; }
.g-fb.ok  .g-verdict { color: var(--green-d); }
.g-fb.bad .g-verdict { color: var(--red); }

.g-answer  { margin: 8px 0 0; font-size: 16px; }
.g-answer b { color: var(--green-d); }
.g-explain { margin: 8px 0 0; font-size: 15px; line-height: 1.65; color: var(--ink); }

/* In the all-questions review the per-question hint is visible again, so it needs separating. */
body.g-live .g-hint { margin-top: 10px; font-style: italic; }

.g-foot { margin: 12px 0 0; }
.g-link {
  background: none; border: 0; padding: 0;
  font-family: var(--read); font-size: 14px; color: var(--blue);
  text-decoration: underline; cursor: pointer;
}
.g-link:hover { color: var(--ink); }

/* ---------- the bar under the exercise ---------- */

.g-bar {
  display: flex; flex-wrap: wrap; gap: 12px; align-items: center;
  margin-top: 18px; padding-top: 18px; border-top: 2px solid var(--line);
}
.g-bar .g-spacer { flex: 1 1 auto; }

.g-prog { font-family: var(--hand); font-size: 16px; color: var(--mut); }
body.g-live .g-bar { border-top: 0; padding-top: 6px; }

/* The score card, written by grammar.js when the exercise is checked. */
.g-score { margin-top: 18px; }
.g-score .g-big {
  font-family: var(--hand); font-weight: 700; font-size: 44px; line-height: 1;
  color: var(--blue); display: block;
}
.g-saved { font-size: 14px; color: var(--mut); margin: 8px 0 0; }

/* ---------- static fallback notice ---------- */

/*
 * Shown to everyone by default and hidden the moment the player boots. It has to tell a reader
 * with no JavaScript something true: the questions and the explanation of the rule are all here
 * and worth their time, and checking answers is the one part that needs scripts.
 */
.g-nojs { font-size: 14px; color: var(--mut); margin: 0 0 14px; }
body.g-live .g-nojs { display: none; }

/*
 * There is deliberately no written-out answer key anywhere in this page. The questions are in
 * the HTML because a crawler and a no-JavaScript reader both need to see the real exercise; the
 * answers are not, because an answer sitting in the markup beside its question is a page Google
 * indexes as an answer list and a learner finishes with view-source. The key is one fetch away,
 * which costs a reader with scripts enabled nothing.
 */

/* ---------- hub and index cards ---------- */

.g-list { display: grid; gap: 14px; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); }

.g-ex {
  display: block; padding: 16px 18px; text-decoration: none; color: inherit;
  border: 2px solid var(--line); border-radius: 12px; background: #fff;
}
.g-ex:hover { border-color: var(--ink); box-shadow: var(--cut); }
.g-ex h3 { font-size: 20px; margin: 0 0 6px; }
.g-ex p { margin: 0; font-size: 14px; color: var(--mut); line-height: 1.5; }

.g-meta { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
.g-tag {
  font-family: var(--hand); font-size: 13px; border: 2px solid var(--line);
  border-radius: 999px; padding: 2px 10px; color: var(--mut);
}
.g-tag.easy   { border-color: #BDE5CD; color: var(--green-d); }
.g-tag.medium { border-color: #F3DFA0; color: #8A6A08; }
.g-tag.hard   { border-color: #F2BDB7; color: #A8322A; }
/* Written by grammar.js from /api/grammar/catalogue - never baked into the cacheable HTML. */
.g-tag.best   { border-color: var(--blue); color: var(--blue); font-weight: 700; }

/* ---------- reference tables ---------- */

.g-ref { width: 100%; border-collapse: collapse; font-size: 15px; }
.g-ref th, .g-ref td { text-align: left; padding: 9px 12px; border-bottom: 1px solid var(--line); vertical-align: top; }
.g-ref th { font-family: var(--hand); font-size: 16px; }
.g-ref td:nth-child(3) { color: var(--mut); font-style: italic; }

.g-wrong { color: var(--red); text-decoration: line-through; }
.g-right { color: var(--green-d); font-weight: 600; }

@media (max-width: 640px) {
  .g-q { padding-left: 44px; }
  .g-ref, .g-ref tbody, .g-ref tr, .g-ref td, .g-ref th { display: block; }
  .g-ref th { padding-bottom: 2px; }
  .g-ref td { border-bottom: 0; padding-top: 2px; }
  .g-ref tr { border-bottom: 1px solid var(--line); padding: 8px 0; }
}
