/* =====================================================================
   TP Bhatia College Library
   A small, dependency-free stylesheet.
   Design goal: a calm reading-room feel. Warm paper tones, one deep
   accent, generous type. No frameworks, no webfonts beyond two.
   ===================================================================== */

:root {
  --paper:        #fbfaf7;
  --paper-2:      #f4f1ea;
  --paper-3:      #eae5da;
  --ink:          #1d1b17;
  --ink-2:        #4a453d;
  --ink-3:        #7a7367;
  --line:         #ded7c9;
  --line-2:       #ebe5d9;

  --accent:       #0f5c4a;   /* deep reading-room green */
  --accent-2:     #0a463a;
  --accent-soft:  #e3efeb;
  --gold:         #a5762a;
  --gold-soft:    #f6edda;

  --ok:           #1d6f42;
  --ok-soft:      #e4f1e8;
  --warn:         #9a5b12;
  --warn-soft:    #fbeeda;
  --danger:       #a02c2c;
  --danger-soft:  #fbe9e9;
  --danger-line:  #e3cccc;   /* the edge a destructive tertiary button carries */
  --info:         #1f4f7a;
  --info-soft:    #e7eff6;

  --radius:       10px;
  --radius-lg:    16px;
  --radius-sm:    7px;
  --shadow-sm:    0 1px 2px rgba(29,27,23,.06), 0 1px 3px rgba(29,27,23,.04);
  --shadow:       0 2px 6px rgba(29,27,23,.07), 0 8px 24px rgba(29,27,23,.06);
  --shadow-lg:    0 8px 16px rgba(29,27,23,.08), 0 24px 48px rgba(29,27,23,.10);

  --serif: "Source Serif 4", Georgia, "Times New Roman", serif;
  --sans:  "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  --mono:  ui-monospace, "SF Mono", "Cascadia Mono", Menlo, Consolas, monospace;

  --wrap: 1180px;
  --header-h: 64px;
}

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

body {
  margin: 0;
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.6;
  color: var(--ink);
  background: var(--paper);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img { max-width: 100%; height: auto; display: block; }
a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }
h1, h2, h3, h4 { font-family: var(--serif); font-weight: 600; line-height: 1.2; margin: 0 0 .5em; letter-spacing: -.01em; }
h1 { font-size: clamp(1.9rem, 4vw, 2.7rem); }
h2 { font-size: clamp(1.35rem, 2.4vw, 1.7rem); }
h3 { font-size: 1.12rem; }
p  { margin: 0 0 1rem; }
code { font-family: var(--mono); font-size: .88em; background: var(--paper-3); padding: .1em .35em; border-radius: 4px; }

.wrap { width: 100%; max-width: var(--wrap); margin: 0 auto; padding: 0 20px; }
.wrap.narrow { max-width: 620px; }
.muted { color: var(--ink-3); }
.dot { color: var(--ink-3); margin: 0 .35em; }

.skip-link {
  position: absolute; left: -9999px; top: 0; z-index: 200;
  background: var(--accent); color: #fff; padding: .7em 1.2em; border-radius: 0 0 var(--radius-sm) 0;
}
.skip-link:focus { left: 0; }

/* ---------------------------------------------------------------- header */
.site-header {
  position: sticky; top: 0; z-index: 60;
  background: rgba(251,250,247,.92);
  backdrop-filter: saturate(1.4) blur(10px);
  border-bottom: 1px solid var(--line);
}
.header-inner { display: flex; align-items: center; gap: 20px; min-height: var(--header-h); }

.brand { display: flex; align-items: center; gap: 11px; color: var(--ink); flex-shrink: 0; }
.brand:hover { text-decoration: none; }
.brand-mark {
  display: grid; place-items: center;
  width: 38px; height: 38px; border-radius: 9px;
  background: var(--accent); color: #fff; flex-shrink: 0;
}
.brand-text { display: flex; flex-direction: column; line-height: 1.15; }
.brand-text strong { font-family: var(--serif); font-size: 1.16rem; font-weight: 700; }
.brand-text small { font-size: .7rem; color: var(--ink-3); letter-spacing: .01em; }

/*
 * The nav sits in the space between the brand and the buttons, centred in it.
 *
 * It was `margin-left: auto` only, which pushed it hard against the buttons and
 * left a ragged gap beside the brand. Worse, nothing stopped a link wrapping: when
 * "Question papers" was added it broke onto two lines, the header grew taller than
 * --header-h, and every other item was shoved along with it - which is what made
 * one new menu item look like it had broken the whole bar.
 *
 * Three things together stop that happening again:
 *   nowrap      a label never breaks onto a second line;
 *   flex: 1 1   the nav may shrink, and the buttons may not, so when space runs
 *               out it is the nav that gives way and the buttons stay put;
 *   centre      margin auto on both sides centres the nav in what is left, which
 *               is what the college asked for, rather than hugging the buttons.
 */
.site-nav {
  display: flex;
  gap: 4px;
  flex: 1 1 auto;
  justify-content: center;
  margin-inline: auto;
  min-width: 0;
  order: 1;
}
.site-nav a {
  color: var(--ink-2); padding: .5em .8em; border-radius: var(--radius-sm);
  font-size: .93rem; font-weight: 500;
  white-space: nowrap;   /* a menu label never becomes two lines */
}
.site-nav a:hover { background: var(--paper-2); color: var(--ink); text-decoration: none; }

.header-actions { display: flex; align-items: center; gap: 8px; flex-shrink: 0; order: 2; }

/*
 * ONE PANEL for the menu and the sign-in links.
 *
 * display:contents takes the wrapper out of the layout entirely, so on a wide
 * screen the bar is laid out by .header-inner exactly as it always was and nothing
 * about it moves. Below 1100px the wrapper becomes the open panel itself, holding
 * the six sections and then the sign-in links together - which is the whole point,
 * because a phone cannot hold six labels and three buttons and used to solve that
 * by hiding two of the three doors.
 *
 * The order numbers are here for the same reason: with the wrapper out of the way,
 * the toggle and the panel's children all become children of .header-inner, and
 * this is what keeps the button at the right-hand end instead of between the brand
 * and the first section.
 */
.header-panel { display: contents; }
.header-actions-label { display: none; }

.nav-toggle {
  order: 3;
  /* Pushed to the far end of the bar, NOT left sitting beside the brand.

     .header-inner is a flex row with no justify-content, so it packs to the left.
     Above 1100px that is invisible - the panel is display:contents, so the sections
     and the sign-in buttons sit between the brand and this button and fill the gap
     anyway. Below 1100px the panel is display:none, which leaves the brand and this
     button as the only two children, and they came out adjacent:

         [icon] Library  [=]

     which is the worst place for it on a phone. The button is 40px wide and sits
     about 20px from the brand's text, so a thumb aiming for the menu has a real
     chance of hitting the brand instead - and the brand goes to the home page, so
     the mistake looks like the site jumping somewhere at random.

     margin-left:auto is the ordinary way to put one item at the end of a flex row,
     and it is the same answer every site with a bar and a hamburger already has. */
  margin-left: auto;
  display: none; flex-direction: column; justify-content: center; gap: 4px;
  width: 40px; height: 40px; border: 1px solid var(--line); background: var(--paper);
  border-radius: var(--radius-sm); cursor: pointer; padding: 0 10px;
  /* 44x44 is the smallest target a thumb reliably lands on; the 40px box is the
     drawn part and the padding below is touch, not paint. */
  position: relative;
}
.nav-toggle::after {
  content: ""; position: absolute; inset: -3px;
}
.nav-toggle span { display: block; height: 2px; background: var(--ink); border-radius: 2px; transition: transform .2s, opacity .2s; }
.nav-toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(6px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-6px) rotate(-45deg); }

/* ---------------------------------------------------------------- buttons */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .5em;
  padding: .68em 1.15em; border-radius: var(--radius-sm);
  font-family: var(--sans); font-size: .92rem; font-weight: 600; line-height: 1.2;
  border: 1px solid transparent; cursor: pointer; white-space: nowrap;
  transition: background .15s, border-color .15s, color .15s, transform .08s, box-shadow .15s;
  text-decoration: none;
}
.btn:hover { text-decoration: none; }
.btn:active { transform: translateY(1px); }
.btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.btn-primary { background: var(--accent); color: #fff; box-shadow: var(--shadow-sm); }
.btn-primary:hover { background: var(--accent-2); }
.btn-outline { background: var(--paper); color: var(--ink); border-color: var(--line); }
.btn-outline:hover { background: var(--paper-2); border-color: var(--ink-3); }

/*
 * Ghost is the TERTIARY action, and it has to have an edge.
 *
 * It was `background: transparent; border-color: transparent`, which is not a
 * button at all - it is a word with padding round it. On a paper card that put
 * Download and Share next to a properly boxed Open, so two of the three actions
 * read as labels and the one that looked like a button looked like the only
 * button. The librarian's row had the same thing: Edit boxed, See and Delete
 * bare. Somebody reading that row would not know which words were things to
 * press, and on a phone, where a bare word has no underline and no box to fall
 * back on, they would not have known at all.
 *
 * So it keeps the quietness that the name is asking for - a lighter edge than
 * outline, softer ink, no shadow - and gains the one thing a word does not have.
 */
.btn-ghost { background: var(--paper); color: var(--ink-2); border-color: var(--line-2); }
.btn-ghost:hover { background: var(--paper-2); border-color: var(--ink-3); color: var(--ink); }

/*
 * The same shape, in red, for the one action in a row that cannot be undone.
 *
 * Delete sat between Edit and See wearing exactly what they wore, so the only
 * thing that said "this one is different" was that it had the most frightening
 * word written on it. That is not enough, and the row it sits in is a row of
 * paper files.
 *
 * The fill goes red on hover and not before. A solid red fill at this size is a
 * shout, and a row of five papers would be five shouts.
 */
.btn-ghost-danger { background: var(--paper); color: var(--danger); border-color: var(--danger-line); }
.btn-ghost-danger:hover { background: var(--danger-soft); border-color: var(--danger); color: var(--danger); }
.btn-quiet { background: transparent; color: var(--accent); border-color: transparent; }
.btn-quiet:hover { background: var(--accent-soft); }
.btn-danger { background: var(--danger); color: #fff; }
.btn-danger:hover { background: #8a2323; }
.btn-sm { padding: .48em .8em; font-size: .84rem; }
.btn-lg { padding: .85em 1.6em; font-size: 1rem; }
.btn-block { width: 100%; }
.btn[disabled] { opacity: .5; pointer-events: none; }

.cta-row { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 26px; }

/* ---------------------------------------------------------------- notices */
.notice { padding: 12px 0; font-size: .92rem; }
.notice-warn { background: var(--warn-soft); color: var(--warn); border-bottom: 1px solid #e8d5b0; }

.flash-area { padding-top: 14px; }
.flash {
  display: flex; align-items: flex-start; gap: 12px;
  padding: 12px 16px; border-radius: var(--radius);
  border: 1px solid; margin-bottom: 10px; font-size: .93rem;
  box-shadow: var(--shadow-sm);
}
.flash-success { background: var(--ok-soft);   border-color: #bcdfc9; color: #14522f; }
.flash-error   { background: var(--danger-soft); border-color: #eec3c3; color: #7d2020; }
.flash-warning { background: var(--warn-soft);  border-color: #ecd5ac; color: #7a470d; }
.flash-info    { background: var(--info-soft);  border-color: #c6d9e9; color: #173a5c; }
.flash-x {
  margin-left: auto; background: none; border: 0; font-size: 1.3rem; line-height: 1;
  cursor: pointer; color: inherit; opacity: .55; padding: 0 2px;
}
.flash-x:hover { opacity: 1; }

/* ---------------------------------------------------------------- hero */
.hero {
  background:
    radial-gradient(1200px 380px at 12% -10%, var(--gold-soft), transparent 62%),
    linear-gradient(180deg, var(--paper) 0%, var(--paper-2) 100%);
  border-bottom: 1px solid var(--line);
  padding: clamp(36px, 6vw, 66px) 0 clamp(40px, 6vw, 70px);
}
.hero-inner { display: grid; grid-template-columns: minmax(0,1.55fr) minmax(0,.85fr); gap: 44px; align-items: start; }
.eyebrow {
  text-transform: uppercase; letter-spacing: .14em; font-size: .72rem;
  font-weight: 700; color: var(--gold); margin: 0 0 12px;
}
.hero h1 { margin: 0 0 14px; letter-spacing: -.02em; }
.lede { font-size: 1.06rem; color: var(--ink-2); max-width: 54ch; }
.hero-hint { font-size: .86rem; color: var(--ink-3); margin-top: 12px; }
.hero-quick { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 22px; }

.chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: .4em .8em; border-radius: 999px;
  background: var(--paper); border: 1px solid var(--line);
  color: var(--ink-2); font-size: .84rem; font-weight: 500;
}
.chip:hover { border-color: var(--accent); color: var(--accent); text-decoration: none; background: var(--accent-soft); }
.chip-n { font-size: .74rem; color: var(--ink-3); background: var(--paper-3); padding: 0 .4em; border-radius: 999px; }

.hero-panel {
  background: var(--paper); border: 1px solid var(--line);
  border-radius: var(--radius-lg); padding: 24px; box-shadow: var(--shadow);
}
.panel-title { font-size: 1rem; margin-bottom: 16px; text-transform: uppercase; letter-spacing: .08em; color: var(--ink-3); font-family: var(--sans); font-weight: 700; }
.panel-note { font-size: .8rem; color: var(--ink-3); margin: 16px 0 0; padding-top: 14px; border-top: 1px solid var(--line-2); }

.statgrid { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; margin: 0; }
.statgrid > div { background: var(--paper-2); border-radius: var(--radius); padding: 14px; }
.statgrid dt { font-size: .74rem; text-transform: uppercase; letter-spacing: .08em; color: var(--ink-3); font-weight: 600; }
.statgrid dd { margin: 4px 0 0; font-family: var(--serif); font-size: 1.75rem; font-weight: 700; line-height: 1; }
.statgrid .stat-hi { background: var(--accent-soft); }
.statgrid .stat-hi dd { color: var(--accent-2); }

/* ---------------------------------------------------------------- searchbar */
.searchbar { position: relative; display: flex; align-items: center; gap: 8px; margin-top: 26px; }
.searchbar-icon { position: absolute; left: 16px; color: var(--ink-3); display: flex; pointer-events: none; }
.searchbar input[type="search"] {
  flex: 1; min-width: 0;
  padding: .95em 1em .95em 3em;
  font-family: var(--sans); font-size: 1rem; color: var(--ink);
  background: var(--paper); border: 1px solid var(--line);
  border-radius: var(--radius); box-shadow: var(--shadow-sm);
}
.searchbar input[type="search"]::placeholder { color: #a49c8e; }
.searchbar input[type="search"]:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.searchbar-lg { margin-top: 18px; }

.suggest {
  position: absolute; top: calc(100% + 6px); left: 0; right: 0; z-index: 50;
  background: var(--paper); border: 1px solid var(--line);
  border-radius: var(--radius); box-shadow: var(--shadow-lg); overflow: hidden;
}
.suggest-item { display: flex; align-items: center; gap: 10px; padding: 10px 14px; cursor: pointer; font-size: .92rem; border-bottom: 1px solid var(--line-2); }
.suggest-item:last-child { border-bottom: 0; }
.suggest-item:hover, .suggest-item.is-active { background: var(--accent-soft); }
.suggest-kind { font-size: .68rem; text-transform: uppercase; letter-spacing: .07em; color: var(--ink-3); background: var(--paper-3); padding: 2px 6px; border-radius: 4px; font-weight: 600; }

/* ---------------------------------------------------------------- sections */
.section { padding: clamp(34px, 5vw, 56px) 0; }
.section-alt { background: var(--paper-2); border-block: 1px solid var(--line); }
.section-head { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; margin-bottom: 22px; flex-wrap: wrap; }
.section-head h2 { margin: 0; }
.link-more { font-size: .9rem; font-weight: 600; white-space: nowrap; }

.search-head { background: var(--paper-2); border-bottom: 1px solid var(--line); padding: 34px 0 26px; }
.search-head h1 { font-size: clamp(1.6rem, 3.2vw, 2.1rem); margin-bottom: 4px; }

.filters { margin-top: 20px; }
.filters summary {
  cursor: pointer; font-size: .88rem; font-weight: 600; color: var(--accent);
  padding: .5em 0; list-style: none;
}
.filters summary::-webkit-details-marker { display: none; }
.filters summary::before { content: "\25B8 "; }
.filters[open] summary::before { content: "\25BE "; }
.filter-row { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 14px; padding: 12px 0 4px; }
.filter-row label { display: flex; flex-direction: column; gap: 5px; font-size: .78rem; font-weight: 600; color: var(--ink-3); text-transform: uppercase; letter-spacing: .05em; }
.filter-row label.check { flex-direction: row; align-items: center; gap: 8px; text-transform: none; letter-spacing: 0; font-size: .9rem; color: var(--ink-2); font-weight: 500; padding-bottom: 8px; }

/*
 * Every text-ish control, in one place.
 *
 * `input:not([type])` is in this list on purpose, and it is the fix for a
 * fault the librarian reported: the "What is it called" and "Remark" boxes on
 * the Holidays screen had no CSS at all and sat there as small default boxes.
 *
 * The reason is a subtlety of CSS rather than a mistake in the styling. An
 * <input> written without a type attribute *behaves* as type="text" - that is
 * the HTML default - but `input[type="text"]` matches on the ATTRIBUTE being
 * present, not on the property defaulting to it. So a typeless input matches
 * none of the selectors below, matches no other rule anywhere in the sheet, and
 * renders exactly as the browser feels like rendering it. The date boxes beside
 * it looked perfect, which is what made it look like the styling was broken
 * rather than the markup.
 *
 * Listing `input:not([type])` closes the whole class of fault: an input cannot
 * be left unstyled by forgetting its type, whatever else is written around it.
 */
select, input:not([type]),
input[type="text"], input[type="search"], input[type="email"], input[type="password"],
input[type="number"], input[type="date"], input[type="tel"], input[type="time"], textarea {
  font-family: var(--sans); font-size: .94rem; color: var(--ink);
  padding: .6em .7em; background: var(--paper);
  border: 1px solid var(--line); border-radius: var(--radius-sm);
  min-width: 0; width: 100%;
}
select:focus, input:focus, textarea:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
textarea { min-height: 96px; resize: vertical; }
input[type="checkbox"], input[type="radio"] { accent-color: var(--accent); width: 16px; height: 16px; }

/*
 * The library's opening and closing times.
 *
 * type="time" was missing from the rule above, so those two settings were the only
 * boxes on the Settings screen drawn entirely by the browser: a different height,
 * a different font, and in some browsers a row of tiny arrow buttons where a clock
 * should be. Adding it to the shared rule is most of the fix; the rest is the pair
 * the two are now drawn in.
 */
.hours {
  grid-column: 1 / -1;
  border: 1px solid var(--line); border-radius: var(--radius-sm);
  padding: 14px 16px;
}
.hours-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 200px)); gap: 14px; }
/* Deliberately the same size as every other box on the screen. Making these two a
   little larger was tried and measured: it left them 1.3px taller and 1.2px
   bigger than the text fields beside them, which is the very thing that made the
   pair look as though it had been dropped in from somewhere else. The tabular
   figures stay, because they line the digits up; the larger size does not. */
.hours-grid input[type="time"] { font-variant-numeric: tabular-nums; color-scheme: light; }
/* The browser's own clock picker is what tells the librarian this is a time and not
   a number, so it is kept - just made to match the rest of the field. */
/* The browser's own clock picker is what tells the librarian this is a time and
   not a number, so it is kept - just made to match the rest of the field. */
.hours-grid input[type="time"]::-webkit-calendar-picker-indicator {
  cursor: pointer; opacity: .5; filter: grayscale(1);
}
.hours-grid input[type="time"]::-webkit-calendar-picker-indicator:hover { opacity: 1; }

.hours-read { margin: 12px 0 0; font-size: .95rem; font-weight: 600; color: var(--ink); }
.hours-read.is-warn { color: #a33; }
.hours .hint { margin-top: 6px; }

/* ---------------------------------------------------------------- book cards */
.book-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 16px; }
.book-card {
  display: flex; flex-direction: column; gap: 6px;
  background: var(--paper); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 16px; color: var(--ink);
  transition: border-color .15s, box-shadow .15s, transform .12s;
}
.book-card:hover { border-color: var(--accent); box-shadow: var(--shadow); transform: translateY(-2px); text-decoration: none; }
.book-card h3 { margin: 0; font-size: 1.02rem; line-height: 1.3; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.book-card-top { display: flex; justify-content: space-between; align-items: center; gap: 8px; }
.book-type { font-size: .68rem; text-transform: uppercase; letter-spacing: .08em; color: var(--ink-3); font-weight: 700; }
.book-author { margin: 0; font-size: .87rem; color: var(--ink-2); }
.book-meta { margin: auto 0 0; padding-top: 8px; font-size: .78rem; color: var(--ink-3); }

.pill { display: inline-block; padding: .18em .6em; border-radius: 999px; font-size: .74rem; font-weight: 700; letter-spacing: .01em; white-space: nowrap; }
.pill-ok   { background: var(--ok-soft); color: var(--ok); }
.pill-mute { background: var(--paper-3); color: var(--ink-3); }
.pill-warn { background: var(--warn-soft); color: var(--warn); }
.pill-danger { background: var(--danger-soft); color: var(--danger); }
.pill-info { background: var(--info-soft); color: var(--info); }
.badge { display: inline-grid; place-items: center; min-width: 20px; height: 20px; padding: 0 5px; border-radius: 999px; font-size: .72rem; font-weight: 700; }
.badge-warn { background: var(--warn); color: #fff; }

/* ---------------------------------------------------------------- results */
.result-count { font-size: .92rem; color: var(--ink-3); margin-bottom: 18px; }
.result-list { display: flex; flex-direction: column; gap: 12px; }
.result {
  display: grid; grid-template-columns: minmax(0,1fr) auto; gap: 24px;
  background: var(--paper); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 20px;
  transition: border-color .15s, box-shadow .15s;
}
.result:hover { border-color: var(--line); box-shadow: var(--shadow-sm); }
.result h2 { font-size: 1.14rem; margin: 0 0 4px; }
.result h2 a { color: var(--ink); }
.result h2 a:hover { color: var(--accent); text-decoration: none; }
.result-sub { margin: 0 0 6px; font-size: .9rem; color: var(--ink-2); font-style: italic; }
.result-by { margin: 0 0 10px; font-size: .9rem; color: var(--ink-2); }
.result-meta { display: flex; flex-wrap: wrap; gap: 6px; margin: 0; }
.tag { display: inline-block; padding: .2em .6em; border-radius: 5px; background: var(--accent-soft); color: var(--accent-2); font-size: .76rem; font-weight: 600; }
.tag-quiet { background: var(--paper-3); color: var(--ink-2); font-weight: 500; }
.result-side { text-align: right; min-width: 168px; display: flex; flex-direction: column; align-items: flex-end; gap: 8px; }
.result-counts { margin: 0; font-size: .8rem; color: var(--ink-3); line-height: 1.45; }
.result-self { margin: 0; font-size: .76rem; color: var(--ink-3); word-break: break-word; }
.result-self code { font-size: .74rem; }
.result-actions { display: flex; gap: 6px; }

.pager { display: flex; gap: 6px; justify-content: center; align-items: center; margin-top: 32px; flex-wrap: wrap; }
.pager a, .pager-cur {
  padding: .5em .85em; border-radius: var(--radius-sm); border: 1px solid var(--line);
  color: var(--ink-2); font-size: .89rem; font-weight: 500; background: var(--paper);
}
.pager a:hover { border-color: var(--accent); color: var(--accent); text-decoration: none; }
.pager-cur { background: var(--accent); color: #fff; border-color: var(--accent); font-weight: 700; }

/* ---------------------------------------------------------------- features */
.feature-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 20px; }
.feature { background: var(--paper); border: 1px solid var(--line); border-radius: var(--radius); padding: 20px; }
.feature h3 { margin: 0 0 8px; font-size: 1.02rem; }
.feature p { margin: 0; font-size: .89rem; color: var(--ink-2); }

.empty { text-align: center; padding: 48px 20px; background: var(--paper-2); border: 1px dashed var(--line); border-radius: var(--radius); }
.empty p { margin: 0 0 6px; }
.errorbox { text-align: center; padding: 40px 0; }
.errorcode { font-family: var(--serif); font-size: 4.4rem; font-weight: 700; color: var(--paper-3); margin: 0; line-height: 1; }
.errorbox h1 { margin: 6px 0 12px; }
.errorbox .cta-row { justify-content: center; }

/* ---------------------------------------------------------------- login */
.auth-wrap { min-height: calc(100vh - var(--header-h) - 120px); display: grid; place-items: center; padding: 40px 20px; }
.auth-card {
  width: 100%; max-width: 430px;
  background: var(--paper); border: 1px solid var(--line);
  border-radius: var(--radius-lg); box-shadow: var(--shadow); overflow: hidden;
}
.auth-head { padding: 28px 30px 22px; border-bottom: 1px solid var(--line-2); text-align: center; }
.auth-head h1 { font-size: 1.5rem; margin: 0 0 4px; }
.auth-head p { margin: 0; font-size: .88rem; color: var(--ink-3); }
.auth-icon {
  width: 46px; height: 46px; border-radius: 12px; display: grid; place-items: center;
  margin: 0 auto 14px; background: var(--accent-soft); color: var(--accent);
}
.auth-body { padding: 26px 30px; }
.auth-foot { padding: 16px 30px 22px; text-align: center; font-size: .85rem; color: var(--ink-3); border-top: 1px solid var(--line-2); }
.auth-alt { display: flex; flex-direction: column; gap: 8px; }

.field { margin-bottom: 16px; }
.field label { display: block; font-size: .8rem; font-weight: 600; color: var(--ink-2); margin-bottom: 5px; text-transform: uppercase; letter-spacing: .04em; }
.field .hint { font-size: .78rem; color: var(--ink-3); margin-top: 5px; }
.input-group { display: flex; }
.input-group input { border-radius: var(--radius-sm) 0 0 var(--radius-sm); }
.input-group .btn { border-radius: 0 var(--radius-sm) var(--radius-sm) 0; }
.auth-error { background: var(--danger-soft); border: 1px solid #eec3c3; color: #7d2020; padding: 11px 14px; border-radius: var(--radius-sm); font-size: .88rem; margin-bottom: 18px; }
.auth-info { background: var(--info-soft); border: 1px solid #c6d9e9; color: #173a5c; padding: 11px 14px; border-radius: var(--radius-sm); font-size: .86rem; margin-bottom: 18px; }

/* ---------------------------------------------------------------- tables */
.table-wrap { overflow-x: auto; border: 1px solid var(--line); border-radius: var(--radius); background: var(--paper); }
table.data { width: 100%; border-collapse: collapse; font-size: .9rem; }
table.data th {
  text-align: left; font-size: .72rem; text-transform: uppercase; letter-spacing: .07em;
  color: var(--ink-3); font-weight: 700; padding: 12px 14px;
  background: var(--paper-2); border-bottom: 1px solid var(--line); white-space: nowrap;
}
table.data td { padding: 11px 14px; border-bottom: 1px solid var(--line-2); vertical-align: top; }
table.data tr:last-child td { border-bottom: 0; }
table.data tbody tr:hover { background: var(--paper-2); }
table.data .num { text-align: right; font-variant-numeric: tabular-nums; }
table.data .nowrap { white-space: nowrap; }

/* ---------------------------------------------------------------- footer */
.site-footer { background: var(--ink); color: #cfc9bd; margin-top: 60px; }
.footer-grid { display: grid; grid-template-columns: 1.6fr 1fr 1fr; gap: 34px; padding-top: 40px; padding-bottom: 30px; }
.site-footer strong { color: #fff; font-family: var(--serif); font-size: 1.05rem; }
.site-footer p { font-size: .88rem; margin: 6px 0 0; }
.site-footer .muted { color: #9b9488; }
.footer-links { list-style: none; padding: 0; margin: 10px 0 0; font-size: .88rem; }
.footer-links li { margin-bottom: 7px; }
.footer-links a { color: #cfc9bd; }
.footer-links a:hover { color: #fff; }
.footer-bottom {
  display: flex; justify-content: space-between; gap: 16px; flex-wrap: wrap;
  border-top: 1px solid #35322c; padding-top: 18px; padding-bottom: 24px; font-size: .82rem;
}

/* ---------------------------------------------------------------- detail */
.bookdetail { display: grid; grid-template-columns: minmax(0,1fr) 320px; gap: 34px; align-items: start; }
.byline { color: var(--ink-2); font-size: 1.02rem; margin-bottom: 16px; }
.pill-row { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 30px; }

.deflist { display: grid; grid-template-columns: minmax(120px, auto) 1fr; gap: 0; margin: 0 0 30px; font-size: .92rem; }
.deflist dt { padding: 9px 16px 9px 0; color: var(--ink-3); border-bottom: 1px solid var(--line-2); font-weight: 600; }
.deflist dd { padding: 9px 0; margin: 0; border-bottom: 1px solid var(--line-2); }

.sidecard { background: var(--paper); border: 1px solid var(--line); border-radius: var(--radius); padding: 20px; margin-bottom: 16px; }
.sidecard .btn { margin-top: 8px; }
.plainlist { list-style: none; padding: 0; margin: 0; font-size: .88rem; }
.plainlist li { padding: 9px 0; border-bottom: 1px solid var(--line-2); }
.plainlist li:last-child { border-bottom: 0; }
.overdue-text { color: var(--danger); font-weight: 600; }

.resource-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 18px; margin-top: 30px; }
.resource { background: var(--paper); border: 1px solid var(--line); border-radius: var(--radius); padding: 22px; }
.resource h2 { font-size: 1.08rem; margin: 6px 0 8px; }
.resource p { margin: 0; font-size: .89rem; color: var(--ink-2); }
.resource-kind { font-size: .68rem; text-transform: uppercase; letter-spacing: .09em; color: var(--gold); font-weight: 700; }

.rules-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 20px; margin-top: 30px; }
.rulecard { background: var(--paper); border: 1px solid var(--line); border-radius: var(--radius); padding: 24px; }
.rulecard h2 { font-size: 1.12rem; margin-bottom: 14px; }
.rulecard .deflist { margin-bottom: 0; }

.subject-cloud { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 24px; }
.chip.is-on { background: var(--accent); color: #fff; border-color: var(--accent); }
.chip.is-on .chip-n { background: rgba(255,255,255,.22); color: #fff; }

/* ---------------------------------------------------------------- responsive */
@media (max-width: 900px) {
  .hero-inner { grid-template-columns: 1fr; gap: 30px; }
  .result { grid-template-columns: 1fr; gap: 14px; }
  .result-side { text-align: left; align-items: flex-start; min-width: 0; }
  .bookdetail { grid-template-columns: 1fr; gap: 26px; }
  .footer-grid { grid-template-columns: 1fr 1fr; }
}

/*
 * THE HEADER BECOMES ONE PANEL, AT 1100px AND NOT AT 720px.
 *
 * It used to switch at 720, which is the width of a phone held UPRIGHT. A phone
 * held sideways is about 900 wide, so in landscape the six section labels were
 * still being laid out across the bar - and pushed Holidays and Rules out from
 * behind the sign-in buttons, with no way to reach them at all. A reader who
 * turned their phone to read more of a page lost the menu in the turning.
 *
 * 1100 covers every phone in either direction and every small tablet, and leaves
 * the full bar for anything that can actually hold it.
 */
@media (max-width: 1100px) {
  .header-panel {
    display: none;
    position: absolute; top: var(--header-h); left: 0; right: 0;
    flex-direction: column; align-items: stretch;
    max-height: calc(100vh - var(--header-h)); overflow-y: auto;
    background: var(--paper); border-bottom: 1px solid var(--line);
    box-shadow: var(--shadow); padding-bottom: 12px;
  }
  .header-panel.is-open { display: flex; }

  .site-nav { flex-direction: column; gap: 0; margin: 0; padding: 6px 0; }
  .site-nav a { padding: .82em 1.1em; font-size: 1rem; border-radius: 0; }
  .site-nav a[aria-current="page"] { background: var(--paper-2); }

  /* The sign-in links, under a line and under a heading, as full-width rows.
     This is where "Student login" now lives on a phone, which is the whole
     reason it is here: it used to be hidden to make room for the Librarian
     button, so the door a student needed was the one that closed. */
  .header-actions {
    flex-direction: column; align-items: stretch; gap: 8px;
    margin: 0 16px; padding-top: 12px; border-top: 1px solid var(--line-2);
  }
  .header-actions-label {
    display: block; font-size: .72rem; letter-spacing: .07em;
    text-transform: uppercase; color: var(--ink-3); margin-bottom: 2px;
  }
  .header-actions .btn { width: 100%; justify-content: center; padding: .8em 1em; }

  .nav-toggle { display: flex; }
  .brand-text small { display: none; }
  /* The brand is the one thing that must never be clipped, so it keeps its size
     and the rest of the bar gives way instead. */
  .header-inner { gap: 12px; }
}

@media (max-width: 720px) {
  .footer-grid { grid-template-columns: 1fr; gap: 24px; }

  /* The magnifying glass belongs to the box, not to the bar.
     .searchbar-icon is absolutely positioned inside .searchbar, which is
     position:relative, and had no `top` - so it sat wherever the flow put it.
     When the bar was told to wrap at 720px, the flow moved the input to the first
     line and the icon with it to the second, next to the button, and the glass
     appeared to be floating on its own below the box it belonged to.

     It is a grid now, the input is the first row and the button the second, and
     the icon is pinned to the first row. */
  .searchbar { display: grid; grid-template-columns: 1fr; gap: 8px; }
  .searchbar-icon { top: 17px; left: 15px; }
  .searchbar .btn { width: 100%; }
  .searchbar input[type="search"] { width: 100%; }

  .filter-row { flex-direction: column; align-items: stretch; }
  .result { padding: 16px; }
  .book-grid { grid-template-columns: 1fr; }
  .statgrid { grid-template-columns: 1fr 1fr; }
  h1 { font-size: 1.75rem; }
}

@media print {
  .site-header, .site-footer, .nav-toggle, .flash-x, .no-print, .cta-row { display: none !important; }
  body { background: #fff; color: #000; font-size: 12pt; }
  .wrap { max-width: 100%; padding: 0; }
  .section { padding: 0; }
  .table-wrap { border: 1px solid #999; }
  a { color: #000; text-decoration: none; }
}

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

/* ---------------------------------------------------------------------------
   The bank's answer, shown on its own.

   The bank's POST comes from secure.ccavenue.com, and a browser may arrive
   here without the librarian's session. Everything worth sending them to
   begins by asking them to sign in, and that is how the reply used to be lost -
   so this page shows the outcome by itself.

   It has to read at a glance and print on its own, because it is what a
   librarian photographs or prints when the bank has behaved oddly.
   --------------------------------------------------------------------------- */
.gate-reply {
  max-width: 34rem;
  margin: 0 auto;
  padding: 28px 20px 32px;
}

.gate-reply h1 {
  margin: 0 0 10px;
  font-size: 1.35rem;
  line-height: 1.25;
}

.gate-reply-detail {
  margin: 0 0 18px;
  color: var(--ink-2);
  font-size: .95rem;
  line-height: 1.55;
}

.gate-reply-rows {
  width: 100%;
  border-collapse: collapse;
  margin: 0 0 20px;
  font-size: .9rem;
}

.gate-reply-rows th,
.gate-reply-rows td {
  text-align: left;
  vertical-align: top;
  padding: 9px 0;
  border-bottom: 1px solid var(--line);
}

.gate-reply-rows th {
  width: 34%;
  padding-right: 14px;
  font-weight: 600;
  color: var(--ink-2);
}

.gate-reply-rows td { color: var(--ink); }
.gate-reply-rows tr:last-child th,
.gate-reply-rows tr:last-child td { border-bottom: 0; }

.gate-reply-more {
  margin: 0 0 16px;
  padding-top: 16px;
  border-top: 1px solid var(--line);
  color: var(--ink-2);
  font-size: .88rem;
  line-height: 1.55;
}

.gate-reply-actions { margin: 0; }
.gate-reply-actions .btn { display: inline-block; }

/* On a phone the label and its value go on their own lines. Side by side, the
   value starts halfway across a 360px screen and wraps after two or three words
   - and the whole point of the table is that the facts are readable. */
@media (max-width: 420px) {
  .gate-reply { padding: 20px 16px 26px; }
  .gate-reply h1 { font-size: 1.18rem; }
  .gate-reply-rows th,
  .gate-reply-rows td { display: block; width: auto; padding: 3px 0; border-bottom: 0; }
  .gate-reply-rows tr { display: block; padding: 9px 0; border-bottom: 1px solid var(--line); }
  .gate-reply-rows tr:last-child { border-bottom: 0; }
  .gate-reply-rows th { padding-bottom: 1px; font-size: .78rem; letter-spacing: .03em; text-transform: uppercase; }
}

/* ==========================================================================
   QUESTION PAPERS

   Split into four blocks, each answering one thing:
     .papers-*      the browse page - filters, list, and what the ask box read
     .paper-*       one paper, its scheme, and what to do with it
     .ask-*         the ask box on its own page
     .scheme-table  the marks, which appear in both of the last two

   The scheme tables are the reason this block is careful about "not set".
   A passing mark of zero and a passing mark nobody has set look identical in a
   database and mean opposite things to a student, so the second one is printed
   in words.
   ========================================================================== */

/* ---- the browse page ---------------------------------------------------- */

.papers-mine {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin: 0 0 18px;
  padding: 14px 18px;
  border-radius: 10px;
  background: var(--accent-soft);
  border: 1px solid #cfe3dc;
}

.papers-filters {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 12px;
  align-items: end;
  margin: 0 0 18px;
  padding: 16px 18px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: #fbfaf7;
}

.papers-filters label { display: flex; flex-direction: column; gap: 4px; }
.papers-filters label > span {
  font-size: .72rem;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--ink-3);
}

/* The class, for a student who has signed in.
   A control that cannot be changed is not a control, and dressing it up as one
   invites the reader to try it. So it is not a <select> and not a disabled
   <select>: it is a label, the answer, and where the answer came from - so the
   student is told the class is not a choice and why it is what it is. It sits
   in the same grid cell a <label> would, so the bar does not reflow. */
.papers-fixed {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 8px 10px;
  border: 1px solid var(--line);
  border-radius: 7px;
  background: #f2f1ec;
  min-height: 38px;
  justify-content: center;
}
.papers-fixed > span {
  font-size: .72rem;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.papers-fixed > strong { font-size: .95rem; line-height: 1.1; }
.papers-fixed > small { font-size: .7rem; color: var(--ink-3); line-height: 1.15; }
.papers-filters select,
.papers-filters input {
  width: 100%;
  padding: 8px 10px;
  border: 1px solid var(--line);
  border-radius: 7px;
  background: #fff;
  font: inherit;
  font-size: .9rem;
  min-height: 38px;
}
.papers-filters select:focus,
.papers-filters input:focus { outline: 2px solid var(--accent); outline-offset: 1px; }

.papers-filter-actions {
  display: flex;
  gap: 8px;
  align-items: center;
}
.papers-filter-actions .btn { min-height: 38px; }

.papers-understood {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin: 0 0 16px;
  padding: 11px 14px;
  border-radius: 8px;
  background: var(--info-soft);
  border: 1px solid #cfdfec;
  font-size: .88rem;
}
.papers-got { color: var(--ink-2); }
.papers-problem { color: #7a470d; }
.papers-count { color: var(--ink-2); font-size: .9rem; margin: 0 0 12px; }

/* ---- a card in the list --------------------------------------------------
   The whole card is one link, and the two buttons beside it are real links too.
   Nesting an <a> inside an <a> is invalid and breaks in some browsers, so the
   title is a link and the row is made clickable with a pseudo-element that
   sits UNDER the buttons rather than over them.
   -------------------------------------------------------------------------- */
.paper-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }

.paper-card {
  position: relative;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 13px 16px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: #fff;
}
.paper-card:hover { border-color: var(--accent); }

.paper-card-main {
  display: flex;
  flex-direction: column;
  gap: 3px;
  color: inherit;
  text-decoration: none;
  flex: 1 1 320px;
}
/* The click target covers the card but never covers the buttons. */
.paper-card-main::after { content: ""; position: absolute; inset: 0; border-radius: 10px; }

.paper-card-subject { font-weight: 600; font-size: .95rem; }
.paper-card-title { font-size: .92rem; color: var(--ink); }
.paper-card-meta { font-size: .8rem; color: var(--ink-3); }

.paper-card-actions { display: flex; gap: 6px; position: relative; z-index: 1; }

.paper-code {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 6px;
  border-radius: 5px;
  background: var(--accent-soft);
  color: var(--accent-2);
  font-family: var(--mono);
  font-size: .74rem;
  font-weight: 600;
}

.pager { display: flex; align-items: center; gap: 12px; justify-content: center; margin: 18px 0 8px; }

/* ---- one paper ---------------------------------------------------------- */

.crumbs { margin: 18px 0 10px; font-size: .85rem; }
.crumbs a { color: var(--ink-2); }

/*
 * THE WAY BACK TO THE LIST.
 *
 * The breadcrumb on a paper's own page was an <a> all along and was styled in
 * the same grey as the text around it - no underline, no colour, no arrow - so
 * it read as a caption. A student looking for the way back had nothing to
 * press, and on a page with a heading, a table and four buttons, a word in grey
 * at the top is a label and not a destination.
 *
 * The arrow is the other half of it: a word with an arrow in front of it is
 * somewhere you can go. The colour stays quiet - it is a way back, not a
 * headline - and it deepens on hover so that it is visibly a link when the
 * pointer is over it.
 */
.crumbs-back {
  display: inline-flex; align-items: center; gap: 6px;
  color: var(--ink-2);
  text-decoration: none;
  border-bottom: 1px solid transparent;
  transition: color .15s, border-color .15s;
}
.crumbs-back span { font-size: 1.05em; line-height: 1; }
.crumbs-back:hover {
  color: var(--accent);
  border-bottom-color: var(--accent);
}

.paper-detail { max-width: 46rem; }
.paper-detail-head h1 { margin: 0 0 6px; font-size: 1.5rem; line-height: 1.25; }
.paper-detail-meta { margin: 0 0 18px; color: var(--ink-2); font-size: .9rem; }

.paper-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin: 0 0 22px;
}
.paper-counts { margin-left: auto; font-size: .8rem; }

.paper-ref { margin-top: 22px; font-size: .82rem; }

.paper-scheme, .paper-more { margin: 26px 0; }
.paper-scheme h2, .paper-more h2 { font-size: 1.1rem; margin: 0 0 6px; }

/* ---- the marks table ---------------------------------------------------- */

.scheme-table {
  width: 100%;
  border-collapse: collapse;
  margin: 12px 0 6px;
  font-size: .88rem;
}
.scheme-table th, .scheme-table td {
  text-align: left;
  padding: 8px 10px;
  border-bottom: 1px solid var(--line);
  vertical-align: top;
}
.scheme-table thead th {
  font-size: .72rem;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--ink-3);
  font-weight: 600;
  border-bottom-width: 2px;
}
.scheme-total td { font-weight: 600; border-bottom: 0; }
.scheme-none td { color: var(--ink-3); font-style: italic; }
.scheme-note { font-size: .82rem; }

.scheme-chip {
  display: inline-block;
  margin: 1px 6px 1px 0;
  padding: 2px 8px;
  border-radius: 20px;
  background: #f1efe8;
  font-size: .8rem;
}
.scheme-chip .muted { font-size: .74rem; }

/* ---- the ask box -------------------------------------------------------- */

.ask-form { display: flex; gap: 8px; margin: 0 0 10px; max-width: 40rem; }
.ask-form input[type="search"] {
  flex: 1 1 auto;
  padding: 11px 14px;
  border: 1px solid var(--line);
  border-radius: 9px;
  font: inherit;
  font-size: 1rem;
  min-height: 46px;
}
.ask-form input:focus { outline: 2px solid var(--accent); outline-offset: 1px; }
.ask-form .btn { min-height: 46px; padding: 0 20px; }

.ask-examples { font-size: .84rem; margin: 0 0 20px; }
.ask-examples a { margin-right: 12px; white-space: nowrap; }

.ask-idle { margin: 30px 0; max-width: 34rem; }

.ask-read {
  margin: 0 0 20px;
  padding: 13px 16px;
  border-radius: 9px;
  background: var(--info-soft);
  border: 1px solid #cfdfec;
  font-size: .88rem;
}
.ask-read-got { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-bottom: 6px; }
.ask-read-no { color: #7a470d; margin-top: 4px; }

.chip {
  display: inline-block;
  padding: 2px 9px;
  border-radius: 20px;
  background: #fff;
  border: 1px solid #c3d5e4;
  font-size: .8rem;
}

.ask-pick { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin: 20px 0; }

.ask-pattern { margin: 0 0 24px; }
.ask-pattern h2 { font-size: 1.15rem; margin: 0 0 6px; }

.pattern-disclaimer {
  margin: 10px 0 0;
  padding: 11px 14px;
  border-left: 3px solid var(--warn);
  background: var(--warn-soft);
  border-radius: 0 7px 7px 0;
  font-size: .86rem;
  line-height: 1.55;
}

.ask-coverage { color: var(--ink-2); font-size: .9rem; margin: 0 0 6px; }
.ask-results-head { font-size: 1.05rem; margin: 22px 0 12px; }

.empty {
  padding: 30px 20px;
  text-align: center;
  border: 1px dashed var(--line);
  border-radius: 10px;
  background: #fbfaf7;
}
.empty p { margin: 0 0 8px; }


/* .box-note lives in desk.css, which is loaded on the desk and not on the public
   site. The paper pages are public, so the quiet-note style is repeated here
   rather than moving it and changing every desk screen that uses it. Two
   definitions of one visual, deliberately, because the alternative is a public
   page with an unstyled warning box - which is worse than a duplicated rule that
   both files can see.
*/
.paper-detail .box-note {
  background: var(--info-soft);
  border: 1px solid #cfdfec;
  color: #1f4f7a;
  padding: 13px 16px;
  border-radius: 8px;
  margin: 0 0 18px;
  font-size: .9rem;
}

/* ---- on a phone ---------------------------------------------------------
   The filter grid drops to one column on its own, but the two things that were
   designed for a wide screen still need help: the card's action buttons wrap
   under the title rather than squeezing it to two words, and the marks table
   scrolls sideways instead of wrapping "Unit Test 1" onto three lines.
   -------------------------------------------------------------------------- */
@media (max-width: 560px) {
  .papers-filters { grid-template-columns: 1fr 1fr; padding: 13px; gap: 10px; }
  /* :first-of-type and :last-of-type, not :nth-child.

     This was :nth-child(1) and :nth-child(7), which counted every child of the
     form - and the first child is the hidden r= field that keeps the route when
     Apply is pressed, not the Subject picker. So both rules had been matching
     nothing since that field was added, and the phone layout silently lost the
     two full-width rows it was written for. -of-type counts only the labels, so
     it keeps meaning "the first picker" and "the last one" whatever else the
     form grows: another hidden field, or the locked Class box a signed-in
     student sees instead of the Class picker. */
  .papers-filters label:first-of-type,
  .papers-filters label:last-of-type,
  .papers-filters .papers-fixed { grid-column: 1 / -1; }
  .papers-filter-actions { grid-column: 1 / -1; justify-content: stretch; }
  .papers-filter-actions .btn { flex: 1 1 auto; justify-content: center; }

  .paper-card { padding: 12px 13px; }
  .paper-card-actions { width: 100%; }
  .paper-card-actions .btn { flex: 1 1 auto; justify-content: center; }

  .paper-counts { margin-left: 0; width: 100%; }

  .scheme-table { display: block; overflow-x: auto; white-space: nowrap; }
  .scheme-table td:last-child { white-space: normal; min-width: 9rem; }

  .ask-form { flex-direction: column; }
  .ask-form .btn { width: 100%; justify-content: center; }
  .ask-examples a { display: inline-block; margin-bottom: 5px; }
}
/* Shown when a question names a subject the college does not run: the twenty
   subjects it DOES run, each one a link back into the ask box. A wall of paper
   titles the student did not ask for would be the wrong answer; a wall of
   subjects they can pick from is a way forward. */
.subject-chips {
  list-style: none;
  margin: 14px 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 7px;
}
.subject-chips a {
  display: inline-block;
  padding: 5px 11px;
  border: 1px solid var(--line);
  border-radius: 20px;
  background: #fff;
  color: var(--ink-2);
  text-decoration: none;
  font-size: .85rem;
}
.subject-chips a:hover { border-color: var(--accent); color: var(--accent); }
.subject-chips .paper-code { margin-left: 4px; }

/* --------------------------------------------------------------------------
   Papers, grouped by subject
   --------------------------------------------------------------------------
   A list of papers sorted by date reads as Chemistry, Electrical Maintenance,
   Chemistry, Psychology - the same subject twice with three others in between.
   Each subject now gets a band of its own and its papers sit under it.

   The band is a link, because the next thing anyone does with a subject that
   has three papers in it is to ask for all three, and the filter bar is four
   controls above.
   -------------------------------------------------------------------------- */

.paper-group { margin: 0 0 22px; }

.paper-group-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 12px;
  margin: 0 0 9px;
  padding: 0 2px 7px;
  border-bottom: 2px solid var(--line);
  font-size: 1.02rem;
  font-weight: 600;
}
.paper-group-head a {
  color: var(--ink);
  text-decoration: none;
}
.paper-group-head a:hover { color: var(--accent); }
.paper-group-head .paper-code { font-size: .74rem; }

.paper-group-meta {
  font-size: .78rem;
  font-weight: 400;
  color: var(--ink-3);
}

/* --------------------------------------------------------------------------
   Paper 1 / Paper 2
   --------------------------------------------------------------------------
   The four vocational subjects run two papers for the same exam, and both rows
   carried the same subject, the same exam and the same date. Nothing on either
   row said which half it was. This badge is the only thing that does.
   -------------------------------------------------------------------------- */

.paper-part {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 7px;
  border: 1px solid var(--line);
  border-radius: 20px;
  background: var(--accent-soft);
  color: var(--accent-2);
  font-size: .7rem;
  font-weight: 600;
  letter-spacing: .02em;
  vertical-align: middle;
  white-space: nowrap;
}

/* --------------------------------------------------------------------------
   Out of, and how long
   --------------------------------------------------------------------------
   These replaced the exam date on the card. A student opening a paper page is
   asking what it is out of and how long they have; a date answers neither, and
   the academic year beside it already says when it was sat.

   Set on their own line and slightly larger than the meta line above, because
   this is the fact the page exists to give.
   -------------------------------------------------------------------------- */

.paper-card-facts { display: flex; flex-wrap: wrap; gap: 6px 16px; margin-top: 5px; }

.paper-fact { display: inline-flex; align-items: baseline; gap: 5px; }

.paper-fact-k {
  font-size: .7rem;
  text-transform: uppercase;
  letter-spacing: .05em;
  color: var(--ink-3);
}

.paper-fact-v {
  font-size: .95rem;
  font-weight: 600;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

/* --------------------------------------------------------------------------
   Share
   --------------------------------------------------------------------------
   A ghost button like every other quiet action in the list, so it does not
   compete with Open. The two end states are brief and coloured, because a
   button that silently changes its own width as it says "Link copied" makes
   the whole row jump on a phone.
   -------------------------------------------------------------------------- */

.share-btn {
  min-width: 4.4rem;
  transition: color .15s ease, border-color .15s ease;
}
.share-btn.share-done { color: var(--ok); border-color: currentColor; }
.share-btn.share-sorry { color: var(--warn); border-color: currentColor; }

/* Older browsers without :focus-visible still get a ring from :focus, which is
   what this replaces for everyone else. */
@media (prefers-reduced-motion: reduce) {
  .share-btn { transition: none; }
}

/* ==========================================================================
   THE PAPERS PAGE - the index, the statistics and the sign-in banner.

   The page answers two questions now. "What is there?" is answered by the
   index - one row per subject, with its numbers. "Show me mine" is answered by
   the filters above it. Neither needs a pager, because twenty rows is a page and
   a subject's papers are about thirty.
   ========================================================================== */

.papers-signin {
  display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
  margin: 18px 0; padding: 16px 18px;
  background: var(--accent-soft);
  border: 1px solid var(--accent);
  border-radius: var(--radius);
}
.papers-signin > div { flex: 1 1 20rem; min-width: 0; }
.papers-signin strong { display: block; font-size: 1.02rem; }
.papers-signin .muted { display: block; margin-top: 3px; font-size: .88rem; }

/* The statistics. One line, and it is the answer to "is this worth looking at". */
.papers-stats {
  display: flex; flex-wrap: wrap; gap: 8px 22px;
  margin: 16px 0 20px; padding: 12px 16px;
  background: var(--paper-2);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  font-size: .88rem; color: var(--ink-2);
}
.papers-stats b { color: var(--ink); font-weight: 700; }

/* The index: one row per subject. */
.papers-index { list-style: none; margin: 0; padding: 0; }
.papers-index-row {
  display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
  padding: 12px 4px;
  border-bottom: 1px solid var(--line);
}
.papers-index-row:last-child { border-bottom: 0; }
.papers-index-name { flex: 1 1 16rem; min-width: 0; }
.papers-index-name a {
  display: inline-block; font-weight: 600; color: var(--ink); text-decoration: none;
}
.papers-index-name a:hover { color: var(--accent); }
.papers-index-count { display: block; margin-top: 2px; font-size: .84rem; color: var(--ink-3); }
.papers-index-years { flex: 1 1 12rem; display: flex; flex-wrap: wrap; gap: 4px 6px; }
.papers-index-year {
  font-size: .74rem; padding: 1px 7px; border-radius: 20px;
  background: var(--paper-2); border: 1px solid var(--line); color: var(--ink-3);
}
.papers-index-totals {
  flex: 0 1 auto; display: flex; gap: 12px; flex-wrap: wrap;
  font-size: .8rem; color: var(--ink-3);
}

/* One subject's papers, under their year. */
.paper-year { margin: 0 0 26px; }
.paper-year-head {
  display: flex; align-items: baseline; gap: 10px;
  margin: 0 0 10px; padding-bottom: 6px;
  border-bottom: 1px solid var(--line);
  font-size: 1rem; font-weight: 600; color: var(--ink);
}
.paper-year-head .muted { font-size: .82rem; font-weight: 400; }

.papers-subject-head {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  margin: 18px 0 16px;
}
.papers-subject-head h2 { margin: 0; font-size: 1.3rem; }
.papers-subject-head .paper-group-meta { font-size: .86rem; color: var(--ink-3); }

.papers-more { display: flex; align-items: center; gap: 12px; margin: 18px 0 4px; }