/* CGPSC study material — shared design system.
 *
 * Single source of truth for both builders:
 *   sources/question-bank/build_questions_html.py   (the previous-year question bank)
 *   pipeline/build_html.py     (the batch study app, and its standalone export mode)
 *   studyqa/                   (the Django app, which links this file rather than inlining it)
 * Each inlines this file at build time, so the pages stay self-contained and offline while a
 * change here lands in both.
 *
 * The palette and the reasoning behind it come from build_questions_html.py, which was built and
 * contrast-checked first. Rules that hold throughout:
 *
 *   1. Every text/background pair meets WCAG 2.1 AA, body text reaches AAA, and interactive
 *      borders and focus rings meet 1.4.11 non-text contrast (>= 3:1).
 *   2. Nothing is distinguished by hue alone (1.4.1). Chips carry a text label, and their group
 *      is coded by fill style: filled = what kind of question, solid outline = where it came
 *      from, dashed outline = a flag about it. That survives colour-vision deficiency, greyscale
 *      printing, and a dark room.
 *   3. One accent hue only. Colour marks what is interactive or stateful; everything else is
 *      ink, muted ink, and surface. A page where five things shout has no emphasis left.
 *   4. Touch targets are at least 44px, so the same page works with a finger on a phone.
 */

/* ---- tokens: light ------------------------------------------------------------------------ */
:root{
  --bg:#F7F9FA; --surface:#FFFFFF; --ink:#14181C; --muted:#59656E;
  --accent:#1F4494; --on-accent:#FFFFFF; --line:#D9E1E5; --edge:#71808A;

  /* Selected-state container. The accent is a light, fairly saturated blue, and a large area of
     it on a near-black background glares — which is why dark themes desaturate their fills
     rather than reusing the light theme's accent. State is therefore carried by a QUIET fill
     with accent-coloured ink on it: high chroma is right on a few pixels of text and wrong on a
     whole button. Four accent-filled controls were on screen at once in fullscreen, and they
     competed with the question, which is the one thing that should be bright. */
  --sel:#E4EAF7; --sel-ink:#1F4494; --sel-edge:#6C86BE;
  --chip-bg:#E7EDF0; --chip-fg:#3B474F; --focus:#1F4494;

  /* panels: quiet fills that stay distinct from --surface without becoming a second accent */
  --panel:#F1F5F8;        /* the answer body */
  --panel-edge:#6E88A0;   /* its leading rule */
  --edit:#EFECF7;         /* the correction editor */
  --edit-edge:#8C7FBF;
  --edit-ink:#453A78;
  --ok-ink:#14603F;       /* "saved" — text and border only, never a fill */
  --no-ink:#9B1C23;       /* the counterpart: a wrong answer. Same rule — ink and border, no fill,
                             so a marked option still reads as an option and not as a warning box. */
  --note-ink:#6B4B12;     /* cautions. Deliberately dark ink, not a bright fill: a caveat should
                             be readable, not the loudest thing on the page. */
  --note-bg:#F6F2E9;

  --serif:Georgia,'Iowan Old Style','Times New Roman',serif;
  --sans:system-ui,-apple-system,'Segoe UI',Roboto,Helvetica,Arial,sans-serif;
  --deva:'Kohinoor Devanagari','Devanagari Sangam MN','Noto Sans Devanagari',var(--sans);
  --sp:clamp(.85rem,2.5vw,1.25rem);
  --radius:10px;
}

/* ---- tokens: dark. Defined for the system default and for the explicit override, so the
 *      toggle wins in both directions and no colour is defined only inside a media query. --- */
@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]){
    --bg:#0E1316; --surface:#171F23; --ink:#E8EFF2; --muted:#9DACB4;
    --accent:#93B0F2; --on-accent:#0E1316; --line:#2A363C; --edge:#7B8B94;
    --sel:#24314A; --sel-ink:#B9C9F7; --sel-edge:#536A9E;
    --chip-bg:#243035; --chip-fg:#AEBDC4; --focus:#93B0F2;
    --panel:#141D22; --panel-edge:#557285;
    --edit:#1D1A28; --edit-edge:#8577C4; --edit-ink:#C3B8F0;
    --ok-ink:#84C9A3; --no-ink:#F2A0A4; --note-ink:#DCBB74; --note-bg:#211D14;
  }
}
:root[data-theme="dark"]{
  --bg:#0E1316; --surface:#171F23; --ink:#E8EFF2; --muted:#9DACB4;
  --accent:#93B0F2; --on-accent:#0E1316; --line:#2A363C; --edge:#7B8B94;
  --sel:#24314A; --sel-ink:#B9C9F7; --sel-edge:#536A9E;
  --chip-bg:#243035; --chip-fg:#AEBDC4; --focus:#93B0F2;
  --panel:#141D22; --panel-edge:#557285;
  --edit:#1D1A28; --edit-edge:#8577C4; --edit-ink:#C3B8F0;
  --ok-ink:#84C9A3; --no-ink:#F2A0A4; --note-ink:#DCBB74; --note-bg:#211D14;
}

/* ---- base --------------------------------------------------------------------------------- */
*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{
  background:var(--bg); color:var(--ink); font-family:var(--sans);
  font-size:clamp(1rem,.97rem + .15vw,1.075rem); line-height:1.6; margin:0;
  -webkit-font-smoothing:antialiased;
}
h1{font-family:var(--serif);font-size:clamp(1.5rem,4vw,2.15rem);line-height:1.15;
  margin:0;letter-spacing:-.015em;text-wrap:balance}
h2,h3{font-family:var(--serif);line-height:1.25;text-wrap:balance}
code{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:.92em}
a{color:var(--accent)}

/* Devanagari needs its own face; it is marked up with lang="hi" so screen readers switch too */
[lang="hi"],.hi{font-family:var(--deva)}

.skip{position:absolute;left:-9999px;top:0}
.skip:focus{left:.5rem;top:.5rem;z-index:99;background:var(--surface);color:var(--ink);
  padding:.6rem .9rem;border:2px solid var(--focus);border-radius:6px}

/* A visible focus ring is the only way a keyboard user knows where they are. */
:focus-visible{outline:2px solid var(--focus);outline-offset:2px;border-radius:4px}

/* ---- controls: 44px minimum so a finger can hit them ------------------------------------- */
button,input,select{font:inherit}
button,select,input[type=search]{
  min-height:44px;padding:.4rem .75rem;border:1px solid var(--edge);
  border-radius:8px;background:var(--surface);color:var(--ink);
}
button{cursor:pointer;transition:background .12s,border-color .12s}
button:hover{background:var(--chip-bg)}
button[disabled]{color:var(--muted);border-color:var(--line);cursor:default;background:var(--surface)}
button.primary{background:var(--accent);border-color:var(--accent);color:var(--on-accent);font-weight:620}
button.primary:hover{filter:brightness(1.1)}
button[aria-pressed="true"]{background:var(--sel);border-color:var(--sel-edge);
  color:var(--sel-ink);font-weight:650}

/* segmented control, e.g. the theme switch */
.seg{display:inline-flex;border:1px solid var(--edge);border-radius:8px;overflow:hidden;
  background:var(--surface)}
.seg button{border:0;border-radius:0;min-height:44px;padding:.4rem .8rem;font-size:.86rem;
  background:transparent}
.seg button+button{border-left:1px solid var(--line)}
.seg button[aria-pressed="true"]{background:var(--sel);color:var(--sel-ink)}

/* ---- chips: label first, fill style second, hue last ------------------------------------- */
.chip{display:inline-flex;align-items:center;gap:.3em;font-size:.72rem;font-weight:600;
  letter-spacing:.02em;padding:.2em .55em;border-radius:5px;border:1px solid transparent;
  white-space:nowrap}
.chip.mains{background:var(--chip-bg);color:var(--chip-fg);border-color:var(--edge)}   /* filled */
.chip.prelims{background:transparent;color:var(--ink);border-color:var(--edge)}         /* outline */
.chip.year{background:var(--sel);color:var(--sel-ink);border-color:var(--sel-edge)}
.chip.meta{background:transparent;color:var(--muted);border-color:var(--line)}          /* solid outline */
/* nowrap is right for a chip holding one short label, and wrong for this one: the flag chip carries
   however many previous-year tags a question has collected, so at four tags it reached 937px inside
   a 760px viewport and made the whole PAGE scroll sideways. It wraps instead. Each tag is bracketed,
   so a break between them still reads correctly. */
.chip.flag{background:transparent;color:var(--chip-fg);border-style:dashed;
  border-color:var(--edge);text-transform:none;letter-spacing:0;
  white-space:normal;max-width:100%}                                                    /* dashed */
.chip.state{background:transparent;color:var(--accent);border-color:var(--accent)}
.chip.state-ok{background:transparent;color:var(--ok-ink);border-color:var(--ok-ink)}
.chip.seq{background:transparent;color:var(--muted);border-color:transparent;padding-left:0;
  font-variant-numeric:tabular-nums}

/* ---- shared surfaces --------------------------------------------------------------------- */
.card{background:var(--surface);border:1px solid var(--line);border-radius:var(--radius);
  padding:clamp(.85rem,3vw,1.05rem)}
.note{padding:.55rem .8rem;border-radius:8px;background:var(--note-bg);color:var(--note-ink);
  border-left:3px solid var(--note-ink);font-size:.86rem}

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

/* ---- print: monochrome, and nothing distinguished by colour ------------------------------ */
@media print{
  :root{--bg:#fff;--surface:#fff;--ink:#000;--muted:#333;--line:#999;--edge:#666;
         --panel:#fff;--panel-edge:#999;--chip-bg:#fff;--chip-fg:#000}
  body{background:#fff;color:#000}
  .chip{border:1px solid #666!important;background:transparent!important;color:#000!important}
  .card{border:1px solid #999;break-inside:avoid;box-shadow:none}
}


/* A square icon button — a control whose whole label is its glyph. In the design system rather than
   in one page's stylesheet because three consumers emit it: the study app's toolbar, the map panel
   that assets/map.js builds for whichever page hosts it, and the reader's own popover. It was in
   study-app.css, which the reader does not load, so the map's close button there had no shape at
   all. 44px square: a control you can see is not the same as one you can hit. */
.icon{display:inline-flex;align-items:center;justify-content:center;
  width:44px;min-width:44px;height:44px;min-height:44px;padding:0;
  border:1px solid var(--edge);border-radius:8px;background:var(--surface);color:var(--ink);
  cursor:pointer;transition:background .12s,border-color .12s;text-decoration:none}
.icon:hover{background:var(--chip-bg)}
.icon svg{display:block}

/* ---- touch ---------------------------------------------------------------------------------------
 * Everything above is sized for a pointer that can hit a 30px target. A finger cannot, and the
 * measurements that prompted this block were taken on the real thing: the reader's back arrow was
 * 22x28, its zoom buttons 26x27, and the cover slider a 16px-tall strip.
 *
 * Keyed on `pointer: coarse` rather than on width, because the two are not the same question — an
 * iPad Pro in landscape is 1180px wide and still driven by a finger, and a 380px browser window on a
 * laptop is narrow and still driven by a mouse. Sizing by width gets both backwards.
 */
@media (pointer: coarse){
  /* 44px is Apple's figure and 48dp Google's; 40 is the floor below which a target is measurably
     harder to hit than the thing beside it. Applied to the CONTROL, not to its text. */
  button, [role=button], select, summary, input[type=checkbox], input[type=radio]{
    min-height:40px;
  }
  /* iOS Safari zooms the whole page when a text field under 16px takes focus, and then leaves it
     zoomed. It is not a preference — 16px is the threshold, so this is 16px. */
  input, select, textarea{font-size:16px}
  /* No 300ms wait for a double-tap the page has no use for. */
  button, a, [role=button], summary{touch-action:manipulation}
  /* A range control's thumb is the target, and its default is a 12px dot. */
  input[type=range]{height:2.5rem}
}

/* The notch, the rounded corners and the home indicator. `env()` is 0 everywhere that has none, so
   these are unconditional — and they are on the elements that actually touch the edges. */
@supports (padding: max(0px)){
  body{
    padding-left:max(0px, env(safe-area-inset-left));
    padding-right:max(0px, env(safe-area-inset-right));
  }
}
