/* Page-specific styles for student-loan-calculator-app.html.
   Shared layout, colours and components live in brand-shared.css (the
   whole site) and calculator-shared.css (every calculator) — this file
   only holds what's unique to this calculator. Structurally this is
   the same .calc-shell system as the other calculators, with a third
   "written off" tone added alongside the usual growth/base pair, because
   this page has to show money that is never repaid at all. */

  /* ---------- student-loan-calculator (scoped) ---------- */

  /* Colours this calculator adds to the shared set in calculator-shared.css
     (a name that appears in both takes this file's value). */
  .calc-shell {
    --surface: #ffffff;
    --growth: #0b6b4f;
    --growth-soft: #e6f4ee;
    --base: #5a6b85;
    --base-soft: #eef1f7;
    /* Money that is written off rather than repaid. Deliberately the
       quietest of the three bar colours: it is the part of the debt that
       never becomes a payment, so it should read as absence. */
    --written: #9aa7bb;
    --warn: #8a4b1f;
    --warn-soft: #fdf1e6;
  }
  @media (prefers-color-scheme: dark) {
    .calc-shell {
      --surface: #17212f;
      --growth: #2dd4a0;
      --growth-soft: #123227;
      --base: #8b9bb4;
      --base-soft: #1d2635;
      --written: #55647a;
      --warn: #e0a878;
      --warn-soft: #2a1d12;
    }
  }

  .calc-shell .ad-rectangle::after { content: "(Responsive, up to 420x260)"; }

  /* Two columns, the same shape as the PAYE calculator: what you type on
     the left, what it works out on the right, so a change and its effect
     are on screen together rather than a scroll apart.

     Three grid children, two columns, two rows:

       col 1 row 1   the input cards
       col 1 row 2   the sidebar ad, sitting in the space under them
       col 2 rows 1-2  the results, which are much taller

     The second row is 1fr rather than auto on purpose. A spanning item
     (the results column) can otherwise push the rows it crosses taller
     than their own content, which would leave a gap between the last
     input card and the ad. Grid does not hand that slack to a flexible
     track's neighbours, so row 1 keeps the height of the inputs alone and
     all the leftover height falls into row 2, below the ad. */
  .calc-shell .layout {
    grid-template-columns: minmax(0, 420px) minmax(0, 1fr);
    grid-template-rows: auto 1fr;
    gap: 22px;
    align-items: start;
  }
  .calc-shell .layout > .col-inputs { grid-column: 1; grid-row: 1; }
  .calc-shell .layout > aside.rail { grid-column: 1; grid-row: 2; align-self: start; }
  .calc-shell .layout > .col-results { grid-column: 2; grid-row: 1 / span 2; }

  /* One column from here down. The cards keep the reading order they have
     in the markup - inputs, then results - and the sidebar ad drops to the
     end rather than sitting between the two, which is where it would land
     if it stayed with the inputs it follows in the source. */
  @media (max-width: 1080px) {
    .calc-shell .layout {
      grid-template-columns: 1fr;
      grid-template-rows: none;
    }
    .calc-shell .layout > .col-inputs,
    .calc-shell .layout > .col-results,
    .calc-shell .layout > aside.rail {
      grid-column: auto;
      grid-row: auto;
    }
    .calc-shell aside.rail { order: 3; }
  }

  /* The columns are plain blocks, so the first card in each sits flush at
     the top and the rest are spaced by the .card + .card rule below. The
     gap between the two columns is the grid's, not a margin. */
  .calc-shell .col > .card:first-child { margin-top: 0; }

  /* One field per row while the inputs are in a column of their own. There
     is about 376px inside those cards, and this calculator's labels are
     long - "Postgraduate: first due to repay", "England, Wales or Northern
     Ireland", "% of salary". Two abreast, the labels wrap to different
     heights and the inputs beside them stop lining up, and the region
     select clips its own longest option. Full width fixes all three, and
     the column still comes out shorter than the results beside it.

     Stated as the base rather than inside a min-width query so that the
     single media query below is the only thing deciding which layout is in
     force - the two can never disagree at a fractional viewport width. */
  .calc-shell .col-inputs .grid-inputs { grid-template-columns: 1fr; }

  /* Cards span the full page width here, so two fields abreast read better
     than one - down to 560px, where .grid-inputs goes to one column for
     every card on the page. */
  @media (max-width: 1080px) and (min-width: 561px) {
    .calc-shell .col-inputs .grid-inputs { grid-template-columns: 1fr 1fr; }
  }
  .calc-shell fieldset:last-of-type { margin-bottom: 0; }
  .calc-shell fieldset legend {
    display: flex;
    align-items: center;
    gap: 14px;
    width: 100%;
    padding: 0;
    padding-top: 14px;
    font-size: 0.74rem;
    font-weight: 700;
    color: var(--ink-soft);
    text-transform: uppercase;
    letter-spacing: .08em;
    margin-bottom: 10px;
  }
  .calc-shell fieldset legend::after {
    content: "";
    flex: 1 1 auto;
    height: 1px;
    background: linear-gradient(90deg, var(--line) 0%, var(--line) 80%, transparent 100%);
  }

  /* Several blocks on this page are shown and hidden with the `hidden`
     attribute, and the browser's own `[hidden] { display: none }` loses to
     any `display` set in here — so a hidden grid would otherwise still be
     laid out as a grid. This puts it back. */
  .calc-shell [hidden] { display: none !important; }

  /* An explanatory paragraph sitting directly above a block of fields
     had nothing between the two - .note carries no bottom margin, and
     the grid none of its own - so the first label ran straight on from
     the prose. */
  .calc-shell .card > p + .grid-inputs { margin-top: 14px; }

  /* ---- the outcome, in colour ----
     Applied by renderHeadline when the balance is cleared rather than
     written off. Only the elements that STATE the outcome change: the
     headline tile and the written-off figure that reads "Nothing".

     There is deliberately no matching red for a write-off. On this system
     being written off usually means paying less overall, which is why the
     page warns against overpaying a loan headed for one - marking it as a
     failure would teach the opposite. Neutral is the honest colour for it,
     and --warn stays reserved for the balance-outgrowing-repayments case,
     which is the only thing on this page that is actually a warning.

     Scoped to .outcome-hero rather than to the first .stat-hero: the tile
     beside it is the total repaid, and tinting THAT green would suggest
     £61,610 on a £45,000 balance is good news. A class also survives the
     tiles being reordered, which a :first-child selector would not. */
  .calc-shell .calc-reveal.is-cleared .outcome-hero {
    background: linear-gradient(160deg, color-mix(in srgb, var(--growth) 13%, var(--surface)), var(--surface));
    border-color: color-mix(in srgb, var(--growth) 26%, var(--line));
  }
  .calc-shell .calc-reveal.is-cleared #rOutcome { color: var(--growth); }
  .calc-shell .calc-reveal.is-cleared #rWrittenOff { color: var(--growth); }

  /* Where the money goes */
  .calc-shell .growth-card {
    background: linear-gradient(160deg, color-mix(in srgb, var(--brand) 9%, var(--surface)), var(--surface));
    border-color: color-mix(in srgb, var(--brand) 26%, var(--line));
  }
  .calc-shell .growth-top { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
  .calc-shell .growth-figure { font-size: clamp(1.8rem, 5vw, 2.6rem); font-weight: 800; color: var(--brand); letter-spacing: -0.02em; }
  .calc-shell .growth-pct {
    font-size: 0.85rem; font-weight: 700; color: var(--accent);
    background: color-mix(in srgb, var(--accent) 16%, transparent);
    padding: 4px 10px; border-radius: 999px;
  }
  .calc-shell .bar {
    background: var(--base-soft);
  }
  /* Three segments, not two: what you repay off the balance, the interest
     you repay on top, and the part that is written off and never repaid at
     all. Default split before calc() runs on load (it runs immediately,
     then JS takes over via el.style.width on every recalculation). */
  .calc-shell .bar .seg-capital { width: 30%; background: linear-gradient(180deg, var(--brand-2), var(--brand)); }
  .calc-shell .bar .seg-interest { width: 20%; background: linear-gradient(180deg, var(--accent), color-mix(in srgb, var(--accent) 72%, #000)); }
  .calc-shell .bar .seg-written { width: 50%; background: repeating-linear-gradient(45deg, var(--written), var(--written) 8px, color-mix(in srgb, var(--written) 80%, #000) 8px, color-mix(in srgb, var(--written) 80%, #000) 16px); }
  .calc-shell .bar span { overflow: hidden; }
  .calc-shell .dot.ct { background: var(--brand); }
  .calc-shell .dot.in { background: var(--accent); }
  .calc-shell .dot.wo { background: var(--written); }
  .calc-shell .stat .sub { font-size: var(--text-small); color: var(--ink-soft); margin-top: 3px; line-height: 1.35; }

  /* Today's-money restatements sit under the cash figure. Set in the accent
     so they read as a second way of looking at the same number rather than
     another number to add up. */
  .calc-shell .sub.real { color: var(--accent); font-weight: 600; }
  .calc-shell table.proj td.gw { color: var(--growth); font-weight: 700; }

  .calc-shell .chart-legend .dot.bal { background: var(--brand); }
  .calc-shell .chart-legend .dot.wo {
    background: transparent;
    border-top: 2px dashed var(--accent);
    height: 0;
    border-radius: 0;
    vertical-align: 4px;
    width: 14px;
  }

  /* ---------- pieces specific to this calculator ---------- */

  /* Checkbox row: the layout is shared; here the whole row is clickable. */
  .calc-shell .check {
    cursor: pointer;
  }
  .calc-shell .check input { flex: none; }

  /* .rate-line, .data-age and .warn-box are shared with Stamp Duty
     (calculator-shared.css). Here the date line sits a little closer under
     the rate box, and there can be a second line under it: */
  .calc-shell .data-age { margin-top: 9px; }
  /* Announced, not yet in force. Accent rather than grey: it is the one
     thing in this corner of the page a reader cannot easily look up. */
  .calc-shell .data-next {
    margin: 9px 0 0;
    font-size: var(--text-small);
    font-weight: 600;
    color: var(--accent);
  }

  /* Overpayment verdict. */
  .calc-shell .verdict-card {
    background: linear-gradient(160deg, color-mix(in srgb, var(--accent) 10%, var(--surface)), var(--surface));
    border-color: color-mix(in srgb, var(--accent) 28%, var(--line));
  }
  .calc-shell .verdict {
    font-size: 1.02rem;
    font-weight: 600;
    line-height: 1.45;
    margin: 0 0 14px;
    text-wrap: pretty;
  }
  .calc-shell .op-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: 12px;
  }
  .calc-shell .op-grid .stat.lead { background: var(--surface); border-color: color-mix(in srgb, var(--accent) 40%, var(--line)); }
  .calc-shell .op-grid .stat.lead .v { color: var(--accent); }

  /* The assumptions behind a 40-year projection matter, but they aren't the
     first thing anyone wants to see, so they fold away. */
  .calc-shell .assumptions {
    margin-top: 16px;
    border-top: 1px solid var(--line);
    padding-top: 14px;
  }
  .calc-shell .assumptions > summary {
    cursor: pointer;
    font-size: var(--text-read);
    font-weight: 600;
    color: var(--ink-soft);
    list-style: none;
    display: flex;
    align-items: center;
    gap: 7px;
  }
  .calc-shell .assumptions > summary::-webkit-details-marker { display: none; }
  .calc-shell .assumptions > summary::before {
    content: "";
    width: 7px; height: 7px;
    border-right: 2px solid currentColor;
    border-bottom: 2px solid currentColor;
    transform: rotate(-45deg);
    transition: transform .18s ease;
    margin-inline-start: 2px;
  }
  .calc-shell .assumptions[open] > summary::before { transform: rotate(45deg); }
  .calc-shell .assumptions .grid-inputs { margin-top: 14px; }
