/* SIS DESIGN SYSTEM v1 · components
 *
 * Everything that draws and that more than one site needs. Lifted from what is already running on
 * the faculty sites rather than redesigned: a design system assembled from guesses is one nobody
 * adopts, and every rule here has survived a lesson.
 *
 * Requires tokens.css from the same version.
 *
 * WHAT IS DELIBERATELY NOT HERE. Technology's lesson engine, its board behaviour, the Primary sound
 * rule, pupil Style mode and the music player. Technology drew that line itself on 11 October and it
 * is the right one: this package renders a menu from data a site provides, and behaviour about
 * lessons stays with the site that owns the lesson.
 *
 * MIGRATING. Swap, do not rewrite: a site replaces its copied colour and bar CSS with these two
 * files, keeps the same tf-* class names, and is checked at 1440 and at board size. One site per
 * quiet window, never mid-lesson.
 *
 * SIS Core, Sardinia International School.
 */

/* THE MENU. One standard for every site, from Maths, which leads here.
 *
 * Kiers, 11 October 2026: "Maths at the moment seems to be leading the way. Technology needs to follow
 * the style of Maths", and "the rule is that technology leads, but this is an exception". So these are
 * Maths's own values rather than a redrawing of them: the standard should be the thing already proven
 * on a screen.
 *
 * Every area gets ONE hue at FOUR strengths, which is what makes a menu read as one object instead of
 * a row of coloured things. Strip, then a near-white panel for the dropdown, a mid border, and a dark
 * bold first item. It is the layers rule applied to a menu.
 *
 * Every pair below was measured against 4.5:1. One Maths value did not reach it and was corrected by
 * three per cent of lightness: see --menu-primary. Full working in MENU-STANDARD.md.
 */
:root {
  /* Everyone, public. A warm neutral, not a school colour, so the strong colours keep meaning
   * something. Maths's choice, and the one part Kiers left open. */
  --menu-public:        #ecebe4;  --menu-public-fg:       #1c2533;
  --menu-public-panel:  #f7f6f1;  --menu-public-border:   #dcd8cc;

  /* Staff, a signed-in teacher. Light yellow, confirmed by Kiers. */
  --menu-staff:       #f7e6c4; --menu-staff-fg:     #6b4a12;
  --menu-staff-panel: #fdf6e8; --menu-staff-border: #ecd3a0;

  /* Secondary. Light blue panel, confirmed by Kiers. */
  --menu-secondary:       #244572; --menu-secondary-fg:     #ffffff;
  --menu-secondary-hover: #1b3357;
  --menu-secondary-panel: #f2f6fb; --menu-secondary-border: #c3d0e3;
  --menu-secondary-first: #244572;

  /* Primary. NOTE the strip is #bb5b32, not the logo orange #c56035: white on #c56035 measures 4.1
   * against the 4.5 a 15px bold tab needs. Same hue, same saturation, three per cent darker.
   * --orange stays #c56035 everywhere else. This is a strip colour, not a change to the logo. */
  --menu-primary:       #bb5b32; --menu-primary-fg:     #ffffff;
  /* Hover goes DARKER, not lighter. White over the strip at .16 lifts it to #c67553 and takes white
   * down to 3.46, worst exactly where the eye is. Found by Maths, which measured the composited
   * states after Core had measured only the base colours. */
  --menu-primary-hover: #a54c28;
  --menu-primary-panel: #fdf1ea; --menu-primary-border: #ecc3ae;
  --menu-primary-first: #9c4626;

  /* Green, derived to the same pattern, since Maths has no green area and one may be wanted. */
  --menu-green:       #617b30; --menu-green-fg:     #ffffff;
  --menu-green-panel: #f6f9f1; --menu-green-border: #d5dfc3;
  --menu-green-first: #617b30;
}

/* TWO RULES THAT ARE NOT COLOURS, and both came from failures that a colour audit cannot see.
 *
 * 1. A strip that only just reaches 4.5 must never hover LIGHTER. Hover down.
 * 2. Never put opacity on a label over a strip. Write the colour you mean. "opacity:.85" on white
 *    reads as #ffffff in the stylesheet and renders at 3.71.
 */

/* The faculty switcher, hanging off the faculty name in the brand row. Kiers, 13 October 2026, with
 * a screenshot: "a little arrow next to the faculty name, which produces a dropdown".
 *
 * tf/bar.css styles .tf-drop and .tf-menu for the TAB row, where the pills are. In the brand row the
 * name is plain text beside the logo, so the arrow needs to sit against it without inheriting a
 * pill's border or height. Only the differences are set here; everything else still comes from
 * Technology's file.
 */
.tf-appdrop { display: inline-flex; align-items: center; position: relative }
.tf-appdt { width: 20px; height: 22px; margin-left: 2px; border: 0; background: transparent;
            cursor: pointer; color: inherit; opacity: .55 }
.tf-appdt:hover, .tf-appdrop.tf-open .tf-appdt { opacity: 1 }
.tf-appdrop .tf-menu { left: auto; right: auto; top: calc(100% + 6px); min-width: 200px }

/* THE TEACHER DASHBOARD on a faculty site. Kiers, 13 October 2026: a checkbox per class, and
 * "text in cards should be top aligned".
 *
 * Top aligned matters more than it sounds: cards hold different amounts (one class has three lines
 * of activity, another has none), and centring makes every card's text sit at a different height,
 * so the eye cannot scan down a row. Aligned to the top, the class names line up and the differences
 * read as differences.
 */
.dpick { display: flex; flex-wrap: wrap; gap: 8px 16px; margin: 0 0 16px }
/* One button per class. The page holds nothing until one is pressed, so opening it costs nothing,
   which matters when it is opened at the start of every lesson. */
.dp { font: inherit; min-height: 48px; padding: 0 20px; border: 2px solid var(--line);
      border-radius: 999px; background: var(--bg); color: var(--fg); font-weight: 700;
      font-size: 16px; cursor: pointer }
.dp:hover { border-color: var(--c-blue) }
.dp.on { background: var(--c-blue); border-color: var(--c-blue); color: var(--c-blue-on) }

.dcards { display: grid; gap: 12px; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
          align-items: start }
.dcard { display: flex; flex-direction: column; align-items: flex-start; justify-content: flex-start;
         background: var(--panel); border: 1px solid var(--line); border-radius: 12px;
         padding: 14px 16px; box-shadow: 0 1px 2px rgba(20, 24, 31, .06) }
.dc-h { display: block; font-size: 17px; margin: 0 0 6px }
.dc-b { font-size: 14px; line-height: 1.5; color: var(--dim); margin: 0 0 12px }
.dc-a { margin-top: 0 }

/* THE LIVE SESSION on a faculty site: the lesson in the room, nothing else.
 * Touch targets are 48px and up because this is tapped mid-lesson, often on a board. */
/* 20 October 2026. These were bare names, and a bare name in this file BEATS the same name in
 * a faculty's own stylesheet, because this file loads last. Form Time styles its own .lv-note
 * in site/ft/play.css and Technology styles .lv-msg in site/style.css, so adopting the shared
 * design would have silently restyled both. points-page.js renders all of these inside
 * <div id="live" class="live">, so scoping them to that parent costs nothing here and cannot
 * reach anything a faculty owns. .lv-grid is gone: nothing in Core ever emitted it, only
 * Technology's own live.js does, and it has its own rule at site/style.css:782. */
.live { margin-top: 14px }
/* Points are never on a big screen (Kiers, 21 Oct 2026). Scoped under .live, like the rest. */
.live .lv-noboard { margin: 0; padding: 26px 28px; border: 1px solid var(--line); border-radius: 12px;
  background: var(--panel); font-size: 26px; line-height: 1.4; color: var(--fg) }
.live .lv-head { font-weight: 700; font-size: 15px; color: var(--dim); margin: 0 0 12px }
.live .lv-msg { margin: 0 0 12px; padding: 10px 14px; border-radius: 10px; font-size: 14px;
          background: var(--c-green-15); border: 1px solid var(--c-green-40) }
.live .lv-note { margin: 0 0 12px; font-size: 14px; color: var(--dim) }

/* THE POINTS TABLE. Kiers, 15 October 2026: "each row needs to record the competency points, the
   toilet / water break (icons). include in each row as a button - headers at the top. Top is fixed
   and doesnt scroll but names list can."
   A row per pupil, a column per thing a teacher can award, and every cell is the button. The header
   is sticky INSIDE the scrolling body, which is why the body is the scroll container and not the
   page: a column of numbers is meaningless once its heading has scrolled off. */
.lv-table { --lv-name: minmax(130px, 1.6fr); border: 1px solid var(--line); border-radius: 12px;
            overflow: hidden; background: var(--panel) }
.lv-body { max-height: min(62vh, 620px); overflow-y: auto; overscroll-behavior: contain }
.lv-prow { display: grid; grid-template-columns: var(--lv-cols); align-items: stretch; gap: 1px;
           background: var(--line) }
.lv-body .lv-prow { border-top: 1px solid var(--line) }
.lv-body .lv-prow:first-child, .lv-body .lv-hrow + .lv-prow { border-top: 0 }

/* The header does not scroll. position: sticky rather than a separate fixed row, so it cannot fall
   out of step with the columns below it. */
.lv-hrow { position: sticky; top: 0; z-index: 2; background: var(--panel);
           border-bottom: 2px solid var(--line) }
.lv-hcell { display: flex; flex-direction: column; align-items: center; justify-content: flex-end;
            gap: 2px; padding: 8px 4px; background: var(--panel); text-align: center;
            font-size: 12px; font-weight: 700; line-height: 1.15; color: var(--dim);
            hyphens: auto; overflow-wrap: anywhere }
.lv-ic { font-size: 17px; line-height: 1 }

.lv-nm { display: flex; align-items: center; padding: 0 12px; background: var(--panel);
         font-weight: 600; font-size: 16px; min-height: 52px;
         overflow: hidden; text-overflow: ellipsis; white-space: nowrap }
.lv-hrow .lv-nm { min-height: 0; font-size: 12px; font-weight: 700; color: var(--dim);
                  align-items: flex-end; padding-bottom: 10px }

/* Every cell is a button. The count lives inside it, so the number a teacher reads and the target
   they tap are the same object and cannot drift apart. */
.lv-cell { font: inherit; font-weight: 700; font-size: 17px; min-height: 52px; cursor: pointer;
           border: 0; background: var(--panel); color: var(--dim);
           font-variant-numeric: tabular-nums }
.lv-cell:hover { background: var(--c-blue-15); color: var(--fg) }
.lv-cell:active { transform: none }
.lv-cell.lv-good.has { background: var(--c-green-15); color: var(--c-green-on-light) }
.lv-cell.lv-out.has { background: var(--c-blue-15); color: var(--fg) }
.lv-cell.lv-good.has:hover { background: var(--c-green); color: var(--c-green-on) }
.lv-cell.lv-out.has:hover { background: var(--c-blue); color: var(--c-blue-on) }
.lv-cell:focus-visible { outline: 3px solid var(--c-blue); outline-offset: -3px }

/* .lv-what, .lv-b and .lv-kid were the two-step layout: a list of pupil pills beside a panel of
   award buttons. The table replaced both on 15 October 2026. Removed rather than left in place, so
   nobody styles against a class the page no longer renders. */

/* The heading above each form's table on View all, where several tables sit one under another and
   a teacher needs to know which class they are looking at before they tap. */
.lv-h2 { margin: 26px 0 10px; font-size: 20px; font-weight: 800; letter-spacing: .01em }
.lv-h2:first-of-type { margin-top: 8px }

/* ── PUPIL PAGES ──────────────────────────────────────────────────────────────────────────────────
   The patterns a page in front of a child uses. Added 19 October 2026 after Kiers said "the whole
   system looks visually very ugly": the staff pages had been rebuilt onto this stylesheet and the
   pupil pages had not, so each carried its own colours written into the markup. DESIGN-PUPIL-PAGES.md
   is the reasoning; these are the pieces. */

/* A door: one of a set of equal choices. The thing the child is looking for is the big text; the
   explanation is small print under it. One colour for the whole set, because the word or the number
   is the signal and a colour code is something they would have to learn first. */
.p-door { display: flex; flex-direction: column; align-items: center; justify-content: center;
          box-sizing: border-box; width: 100%; min-height: 84px; padding: 10px 18px;
          border-radius: 14px; text-align: center; text-decoration: none;
          background: var(--door); border: 2px solid var(--door-edge); color: var(--door-on) }
.p-door:hover { background: var(--door-edge) }
.p-door:focus-visible { outline: 3px solid var(--c-blue); outline-offset: 2px }
.p-door-big { font-size: 40px; font-weight: 800; line-height: 1.05 }
.p-door-sub { font-size: 13px; font-weight: 600; line-height: 1.25; margin-top: 3px; color: var(--dim) }
.p-doors { display: grid; gap: 12px; max-width: 460px }

/* English first, Italian under it, smaller and lighter, in the same place on every page. */
.p-en { display: block }
.p-it { display: block; font-style: italic; font-weight: 400; color: var(--dim) }

/* A panel inside a panel changes TONE and gains a very small shadow. Never a heavier border:
   stacked borders are what make a page look like a form from 1998. */
.p-panel { background: var(--panel); border: 1px solid var(--line); border-radius: 14px; padding: 18px }
.p-panel .p-panel { background: var(--bg); border: 0; box-shadow: 0 1px 2px rgba(2, 6, 23, .06) }

/* Anything a child taps: 48px on a device, 72px on a board, 12px apart so a whole hand on a 2.5 m
   screen cannot hit two at once. */
.p-tap { min-height: 48px; min-width: 48px }
@media (min-width: 2400px) {
  .p-door { min-height: 128px; border-radius: 18px }
  .p-door-big { font-size: 64px }
  .p-door-sub { font-size: 18px }
  .p-doors { gap: 18px; max-width: none }
  .p-tap { min-height: 72px; min-width: 72px }
}

/* A board, about 2.5 m wide and touched standing up. Everything grows; nothing new appears. The
   table gets more height too, because a board shows a whole class without scrolling and scrolling a
   long list in front of thirty children is how a teacher loses the room. */
@media (min-width: 2400px) {
  .lv-nm { min-height: 86px; font-size: 30px; padding: 0 20px }
  .lv-cell { min-height: 86px; font-size: 30px }
  .lv-hcell { font-size: 19px; padding: 12px 6px }
  .lv-ic { font-size: 26px }
  .lv-hrow .lv-nm { font-size: 19px; padding-bottom: 14px }
  .lv-body { max-height: 76vh }
}

/* The forms menu across the top of a points section: View all, then each form. Lived only in Core's
 * own stylesheet until 14 October 2026, so on a faculty site it rendered as bare links and Kiers
 * reported "View All does nothing". A class used by more than one site is the definition of shared. */
.row.forms { display: flex; flex-wrap: wrap; gap: 8px; align-items: center;
             margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--line, #D6D1C4) }

/* A failure a person can read. An error that renders as an empty list is the failure mode that has
 * cost this project the most time: it looks like a quiet day. */
.err { margin: 10px 0 0; padding: 10px 14px; border-radius: var(--r-sm, 8px); font-size: 14px;
       background: var(--c-red-15); border: 1px solid var(--c-red-40); color: var(--fg, #14181F) }

/* ── THE PUPIL LESSON PIECES ───────────────────────────────────────────────────────────────────────
   The eight the Technology chat had to invent locally on 19 October 2026 while applying design/v1 to
   its lesson pages, listed back to Core the same evening. Built here so they exist once.

   Every one follows DESIGN-PUPIL-PAGES.md: the thing the child came for is the biggest element, the
   word carries the meaning and never the colour alone, anything tappable is 48px and 72px on a board,
   and the Italian sits under the English in the same place every time. Tokens only: there is not a
   hex value anywhere below. */

/* 4 · WHERE WE ARE. The strip across the top of a lesson: one mark per step, and a badge saying
   which. Status is the WORD plus the shape; a colour-blind child and a board seen at an angle both
   read it the same. */
.p-track { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin: 0 0 14px }
.p-track-i { display: inline-flex; align-items: center; justify-content: center; min-width: 28px;
          height: 10px; padding: 0 6px; border-radius: 999px;
          background: var(--line); border: 1px solid transparent }
.p-track-i.is-done { background: var(--c-green); border-color: var(--c-green) }
.p-track-i.is-now  { background: var(--c-blue); border-color: var(--c-blue); min-width: 52px }
.p-track-i.is-later { background: transparent; border-color: var(--line) }
.p-track-n { display: inline-flex; align-items: baseline; gap: 4px; margin-left: 8px;
           font-weight: 800; font-variant-numeric: tabular-nums; color: var(--dim) }
.p-track-n b { font-size: var(--type-xl); color: var(--fg) }

/* 7 · WHAT STATE SOMETHING IS IN, said in words. Never put one of these on a page using colour alone:
   the text inside it is the message, the tint only agrees with it. */
.p-status { display: inline-flex; align-items: center; gap: 6px; padding: 3px 10px; border-radius: 999px;
            font-size: var(--type-sm); font-weight: 700; border: 1px solid var(--line);
            background: var(--bg); color: var(--dim) }
.p-status.is-now   { background: var(--c-blue-15);  border-color: var(--c-blue-40);  color: var(--c-blue) }
.p-status.is-done  { background: var(--c-green-15); border-color: var(--c-green-40); color: var(--c-green) }
.p-status.is-later { background: var(--bg); border-color: var(--line); color: var(--dim) }

/* 6 · TODAY'S STEPS, numbered, and the heading of the one you are on. The number is a badge rather
   than a list marker so it survives being read across a room. */
.p-tasks { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px }
.p-task { display: flex; align-items: flex-start; gap: 12px; padding: 12px 14px;
          background: var(--panel); border: 1px solid var(--line); border-radius: 12px }
.p-task.is-now { border-color: var(--c-blue); box-shadow: 0 1px 2px rgba(2, 6, 23, .06) }
.p-task.is-done .p-task-t { color: var(--dim) }
.p-task-n { flex: none; display: inline-flex; align-items: center; justify-content: center;
            min-width: 34px; height: 34px; border-radius: 999px; font-weight: 800;
            font-variant-numeric: tabular-nums;
            background: var(--c-blue-15); color: var(--c-blue) }
.p-task.is-done .p-task-n { background: var(--c-green-15); color: var(--c-green) }
.p-task-b { min-width: 0 }
.p-task-t { font-size: var(--type-lg); font-weight: 700; line-height: 1.25 }

/* The heading of the step a pupil is actually on: a number, then THE BIG THING. */
.p-head { display: flex; align-items: center; gap: 14px; margin: 0 0 6px }
.p-head .p-task-n { min-width: 46px; height: 46px; font-size: var(--type-xl) }
.p-title { font-size: var(--type-3xl); font-weight: 800; line-height: 1.05; margin: 0 }

/* 11 · The Italian under a heading, and any other line of help. Smaller, lighter, same place every
   time, so a child looking for their language stops hunting. */
.p-help { font-size: var(--type-sm); line-height: 1.35; color: var(--dim); margin: 4px 0 0 }
.p-help i { font-style: italic }

/* 5 · BACK AND NEXT. The pair a pupil presses all lesson, so they are the biggest targets on the page
   and they never move. Next is the one they want, so it is the solid one. */
.p-nav { display: flex; align-items: center; gap: 12px; margin: 20px 0 0 }
.p-nav .p-sp { flex: 1 }
.p-nav a, .p-nav button { display: inline-flex; align-items: center; justify-content: center; gap: 8px;
                          min-height: 48px; padding: 0 22px; border-radius: 12px; cursor: pointer;
                          font: inherit; font-size: var(--type-lg); font-weight: 700;
                          text-decoration: none; border: 2px solid var(--c-blue);
                          background: var(--panel); color: var(--c-blue) }
.p-nav .p-next { background: var(--c-blue); color: var(--c-blue-on) }
.p-nav a:focus-visible, .p-nav button:focus-visible { outline: 3px solid var(--c-yellow); outline-offset: 2px }
.p-nav [aria-disabled="true"], .p-nav button:disabled { opacity: .45; cursor: default }

/* 8 · A QUESTION AND ITS ANSWERS. The question is the big thing; the options are equal, one colour,
   because which one is right is not something the page should hint at. */
.p-q { background: var(--panel); border: 1px solid var(--line); border-radius: 14px; padding: 18px }
.p-q-t { font-size: var(--type-xl); font-weight: 700; line-height: 1.3; margin: 0 0 4px }
.p-opts { display: grid; gap: 10px; margin: 14px 0 0 }
.p-opt { display: flex; align-items: center; gap: 12px; width: 100%; min-height: 56px;
         padding: 10px 16px; border-radius: 12px; cursor: pointer; text-align: left;
         font: inherit; font-size: var(--type-lg); font-weight: 600;
         background: var(--bg); border: 2px solid var(--line); color: var(--fg) }
.p-opt:hover { border-color: var(--c-blue) }
.p-opt[aria-pressed="true"] { background: var(--c-blue-15); border-color: var(--c-blue) }
.p-opt:focus-visible { outline: 3px solid var(--c-yellow); outline-offset: 2px }
.p-opt-k { flex: none; display: inline-flex; align-items: center; justify-content: center;
           min-width: 30px; height: 30px; border-radius: 8px; font-weight: 800;
           background: var(--panel); border: 1px solid var(--line); color: var(--dim) }

/* 9 · WHERE A PUPIL WRITES. 48px minimum, a visible focus ring, and a label that is part of the
   field rather than floating above it. */
.p-field { display: block; margin: 0 0 14px }
.p-field > span { display: block; font-size: var(--type-md); font-weight: 700; margin: 0 0 4px }
.p-input, .p-write { display: block; box-sizing: border-box; width: 100%; font: inherit;
                     font-size: var(--type-lg); padding: 12px 14px; border-radius: 12px;
                     background: var(--panel); border: 2px solid var(--line); color: var(--fg) }
.p-input { min-height: 48px }
.p-write { min-height: 132px; line-height: 1.5; resize: vertical }
.p-input:focus-visible, .p-write:focus-visible { outline: 3px solid var(--c-yellow); outline-offset: 1px;
                                                 border-color: var(--c-blue) }

/* 10 · MY WORK. The links out to a pupil's own files. A panel rather than loose links, because it is
   one idea, and the destination is named so nobody taps hopefully. */
.p-work { display: grid; gap: 8px; padding: 14px; border-radius: 14px;
          background: var(--panel); border: 1px solid var(--line) }
.p-work-t { font-size: var(--type-md); font-weight: 800; color: var(--dim);
            letter-spacing: .08em; text-transform: uppercase; margin: 0 0 2px }
.p-work a { display: flex; align-items: center; gap: 10px; min-height: 48px; padding: 8px 12px;
            border-radius: 10px; text-decoration: none; font-weight: 700;
            background: var(--bg); border: 1px solid var(--line); color: var(--fg) }
.p-work a:hover { border-color: var(--c-blue); color: var(--c-blue) }
.p-work a:focus-visible { outline: 3px solid var(--c-yellow); outline-offset: 2px }

/* A board, 2.5 m wide, read from the back and tapped with a whole hand. Everything grows; nothing new
   appears, and nothing is revealed here that was hidden on a device. */
@media (min-width: 2400px) {
  .p-track-i { height: 16px; min-width: 40px } .p-track-i.is-now { min-width: 80px }
  .p-task { padding: 18px 20px; gap: 18px }
  .p-task-n { min-width: 52px; height: 52px; font-size: var(--type-lg) }
  .p-head .p-task-n { min-width: 72px; height: 72px }
  .p-nav a, .p-nav button { min-height: 72px; padding: 0 34px; font-size: var(--type-xl) }
  .p-opt { min-height: 84px; font-size: var(--type-xl) }
  .p-opt-k { min-width: 44px; height: 44px }
  .p-input { min-height: 72px } .p-write { min-height: 200px }
  .p-work a { min-height: 72px; font-size: var(--type-lg) }
  .p-status { font-size: var(--type-md); padding: 6px 16px }
}
