/* som-sg.info — design system, copied verbatim from self-host-ballot/public/assets/site.css
   on 2026-09-16 so the two SG sites look like one (Thomas: match the deployed ballot).
   Tokens originate in ballotcssjs/handoff/01-tokens.css (school-confirmed
   palette, fluid type ramp). Self-hosted fonts: no external requests at all. */

@font-face { font-family:'Yale'; src:url('/assets/fonts/Yale2024-Roman.woff2') format('woff2');      font-weight:400; font-style:normal; font-display:swap; }
@font-face { font-family:'Yale'; src:url('/assets/fonts/Yale2024-Italic.woff2') format('woff2');     font-weight:400; font-style:italic; font-display:swap; }
@font-face { font-family:'Yale'; src:url('/assets/fonts/Yale2024-Bold.woff2') format('woff2');       font-weight:700; font-style:normal; font-display:swap; }
@font-face { font-family:'Yale'; src:url('/assets/fonts/Yale2024-BoldItalic.woff2') format('woff2'); font-weight:700; font-style:italic; font-display:swap; }
@font-face { font-family:'Puritan'; src:url('/assets/fonts/Puritan-Regular.woff2') format('woff2');    font-weight:400; font-style:normal; font-display:swap; }
@font-face { font-family:'Puritan'; src:url('/assets/fonts/Puritan-Italic.woff2') format('woff2');     font-weight:400; font-style:italic; font-display:swap; }
@font-face { font-family:'Puritan'; src:url('/assets/fonts/Puritan-Bold.woff2') format('woff2');       font-weight:700; font-style:normal; font-display:swap; }
@font-face { font-family:'Puritan'; src:url('/assets/fonts/Puritan-BoldItalic.woff2') format('woff2'); font-weight:700; font-style:italic; font-display:swap; }

:root{
  --serif:'Yale',Georgia,serif;
  --sans:'Puritan',Verdana,'DejaVu Sans',sans-serif;
  --fs-mark:clamp(30px,1.25vw + 26.00px,44px);
  --fs-display:clamp(27px,1.16vw + 23.29px,40px);
  --fs-section:clamp(21px,0.54vw + 19.29px,27px);
  --fs-subhead:clamp(18px,0.36vw + 16.86px,22px);
  --fs-body:clamp(16px,0.18vw + 15.43px,18px);
  --fs-meta:clamp(14px,0.09vw + 13.71px,15px);
  --fs-label:clamp(13px,0.09vw + 12.71px,14px);
  --lh-tight:1.2; --lh-body:1.6; --lh-meta:1.5;
  --track-label:.14em;
  /* The reading measure. 500px was the school canon's phone-first value and read
     as a narrow strip on a desktop (Thomas, 2026-09-07: "at minimum 850px for
     really wide screens"). It now steps up with the viewport; on a phone the
     container is narrower than any of these anyway. */
  --measure:100%;

  --ground:#DDDDDD; --paper:#F9F9F9; --raised:#FFFFFF; --row:#F4F4F4; --bar:#EAEAEA;
  --wash-pill:#EAF2FB; --wash-flash:#DCE9F7;
  --action:#00356B; --ink-head:#00356B; --ink-body:#222222; --ink-meta:#4A4A4A; --ink-mute:#978D85;
  --danger:#BD5319;  /* Yale orange. Nothing in this system is red. */
  --affirm:#5F712D;

  --s1:4px; --s2:8px; --s3:12px; --s4:16px; --s5:24px; --s6:32px; --s7:48px; --s8:64px;
  --gutter:16px; --shell:1320px;
  /* How far the nav group may travel from the wordmark. Left-aligned
     inside --shell, so the wordmark keeps the h1's left edge (N3). */
  --shell-bar:1040px;
  --r-sm:6px; --r-md:12px; --r-pill:999px;
  --d-fast:160ms; --d-base:240ms; --d-slow:300ms;
  --e-out:cubic-bezier(.2,.8,.3,1);
}
@media (min-width:640px){ :root{ --gutter:24px; } }
@media (min-width:1024px){ :root{ --gutter:32px; } }

*,*::before,*::after{ box-sizing:border-box; }
html{ -webkit-text-size-adjust:100%; }
body{
  margin:0; background:var(--ground); color:var(--ink-body);
  font-family:var(--sans); font-size:var(--fs-body); line-height:var(--lh-body);
}
h1,h2,h3,h4{ font-family:var(--serif); color:var(--ink-head); line-height:var(--lh-tight); margin:0 0 var(--s3); font-weight:400; }
h1{ font-size:var(--fs-display); }
h2{ font-size:var(--fs-section); }
h3{ font-size:var(--fs-subhead); }
p{ margin:0 0 var(--s4); }
a{ color:var(--action); }

/* One focus style, everywhere, no exceptions. */
:focus-visible{ outline:2px solid var(--action); outline-offset:2px; }

.shell{ width:min(100% - 2*var(--gutter),var(--shell)); margin-inline:auto; }
/* Bar only: same left edge as .shell, but the nav stops short of the far
   right rather than being flung to it by margin-left:auto. */
.masthead__in{ max-width:var(--shell-bar); margin-right:auto; }
.measure{ max-width:var(--measure); }

/* ── Masthead ─────────────────────────────────────────────────────────────── */
.masthead{ background:var(--raised); border-bottom:1px solid var(--bar); position:sticky; top:0; z-index:20; }
.masthead__in{ display:flex; align-items:center; gap:var(--s5); min-height:56px; }
@media (min-width:768px){ .masthead__in{ min-height:64px; } }
@media (min-width:1024px){ .masthead__in{ min-height:72px; } }
@media (min-width:768px){ .masthead__in{ min-height:64px; } }
/* "Yale" sits at full size in the serif; the unit name sits beside it, never
   under it. The two are sized so the O of SOM stands exactly as tall as the e
   of Yale — measured from the shipped fonts, not eyeballed:

     Yale 2024 Roman  e tops at 0.4420 em
     Puritan Regular  O tops at 0.6465 em   (round letters overshoot the cap)
     ratio = 0.4420 / 0.6465 = 0.6837

   Keeping that as a variable means the relationship survives a size change. */
/* C1: the school word is ALWAYS serif, even though the nav beside it is not —
   the lockup is the only serif in the bar. It is sized so its cap-height meets
   the x-height of the e in Yale. C6/C1 give that ratio as 0.686; measuring the
   shipped fonts puts it at 0.6811 (Yale 2024 e tops at 0.4420 em, O at 0.6490),
   which agrees to within 0.7% — so the canonical number stands. */
/* SIZE. C1 gives one authoritative measurement: at a 390 viewport the lockup
   is 101px — 30px Yale with SOM at 20px. This was set to --fs-subhead (18-22px),
   which rendered it around a third too small. It now starts at exactly 30px and
   scales with the header itself (56px -> 72px, so 30px -> 38px), on the same
   fluid-clamp pattern as the type ramp.
   GAP. Every lockup drawn in the canvas sits at 0.25em — 11/44, 6/24, 7/28.
   This was 0.45em, nearly double, which is the loose look. */
.wordmark{ --unit-ratio:0.686;
  display:flex; align-items:baseline; gap:0.25em;
  font-family:var(--serif); font-size:clamp(30px, 0.762vw + 27.03px, 38px);
  line-height:1; color:var(--ink-head);
  text-decoration:none; white-space:nowrap; }
.wordmark__unit{ font-family:var(--serif); font-size:calc(1em * var(--unit-ratio));
  letter-spacing:.05em; text-transform:uppercase; color:var(--ink-meta); }
/* C1 draws the full name at 1440 and SOM at 1024 and below. */
.wordmark__long{ display:none; }
@media (min-width:1440px){
  .wordmark__long{ display:inline; }
  .wordmark__short{ display:none; }
}
.nav{ display:flex; gap:var(--s4); margin-left:auto; align-items:center; flex-wrap:wrap; }
.nav a{ font-size:var(--fs-meta); color:var(--ink-body); text-decoration:none; padding:var(--s2) 0; border-bottom:2px solid transparent; }
.nav a[aria-current="page"]{ color:var(--action); border-bottom-color:var(--action); }
.nav a.nav--past{ color:var(--ink-mute); }
.nav a.nav--past[aria-current="page"]{ color:var(--ink-meta); border-bottom-color:var(--ink-mute); }
/* The admin's way out of a stage preview. Absolutely placed in the masthead so
   it adds no height and moves nothing; 11px so it reads as an instrument, not
   as part of the site. */
.preview-exit{ position:absolute; top:0; right:8px; margin:0; z-index:1; line-height:1; }
.preview-exit button{ background:none; border:0; padding:2px 4px; cursor:pointer;
  font-family:var(--sans); font-size:10px; letter-spacing:.08em; color:#C0392B; line-height:14px; }
.preview-exit button:hover{ text-decoration:underline; }

/* ── Blocks ───────────────────────────────────────────────────────────────── */
main{ padding:var(--s6) 0 var(--s8); }
.card{ background:var(--raised); border:1px solid var(--bar); border-radius:var(--r-md); padding:var(--s5); }
.card + .card{ margin-top:var(--s4); }
.cand-grid > .card + .card, .roles > .card + .card{ margin-top:0; }
.stack > * + *{ margin-top:var(--s4); }
.meta{ font-size:var(--fs-meta); line-height:var(--lh-meta); color:var(--ink-meta); }
.label{ display:block; font-size:var(--fs-label); font-weight:700; letter-spacing:var(--track-label);
  text-transform:uppercase; color:var(--ink-meta); margin-bottom:var(--s2); }

input[type=text],input[type=email],input[type=search],textarea,select{
  width:100%; font-family:var(--sans); font-size:var(--fs-body); color:var(--ink-body);
  background:var(--paper); border:1px solid var(--bar); border-radius:var(--r-sm); padding:var(--s3);
}
textarea{ line-height:var(--lh-body); resize:vertical; min-height:9rem; }
.btn{ display:inline-flex; align-items:center; justify-content:center; gap:var(--s2);
  min-height:44px; padding:0 var(--s5); border:1px solid var(--action); border-radius:var(--r-sm);
  background:var(--action); color:#fff; font-family:var(--sans); font-size:var(--fs-body);
  text-decoration:none; cursor:pointer; transition:opacity var(--d-fast) var(--e-out); }
.btn:hover{ opacity:.9; }
.btn--ghost{ background:transparent; color:var(--action); }
/* C1: the filled blue pill is reserved for Vote, the site's one primary path.
   Every other affirmative control uses this: bar grey, Yale Blue lettering,
   10.14:1. Same treatment as .wink-pill. */
.btn--quiet{ background:var(--bar); color:var(--action); border:0; }
.btn--quiet:hover:not(:disabled){ background:#DFE6EF; }
.btn[disabled]{ opacity:.45; cursor:not-allowed; }

.notice{ border-left:3px solid var(--action); background:var(--wash-pill);
  padding:var(--s3) var(--s4); border-radius:0 var(--r-sm) var(--r-sm) 0; font-size:var(--fs-meta); }
.notice--warn{ border-left-color:var(--danger); background:#FBEFE8; }
.notice--ok{ border-left-color:var(--affirm); background:#EDF1E4; }

/* ── Sign-in ──────────────────────────────────────────────────────────────── */
.centre{ min-height:100dvh; display:flex; align-items:center; justify-content:center; padding:var(--s5); }
.panel{ width:100%; max-width:420px; background:var(--raised); border:1px solid var(--bar);
  border-radius:var(--r-md); padding:var(--s6); }
.code-input{ font-family:ui-monospace,'SF Mono',Menlo,monospace; font-size:28px;
  letter-spacing:.3em; text-align:center; padding:var(--s4) var(--s3); }

/* Reduced motion removes the travel, not the information. */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{ animation-duration:.01ms !important; transition-duration:.01ms !important; }
}
.sr{ position:absolute; width:1px; height:1px; padding:0; margin:-1px; overflow:hidden;
  clip:rect(0,0,0,0); white-space:nowrap; border:0; }

/* ── C1 skip link ─────────────────────────────────────────────────────────── */
/* First in DOM order, visible on focus only, 44px tall, Yale Blue on white. */
.skip{ position:absolute; left:-9999px; top:0; z-index:50;
  display:inline-flex; align-items:center; min-height:44px; padding:0 var(--s4);
  background:var(--raised); color:var(--action); font-size:var(--fs-meta); }
.skip:focus-visible{ left:var(--s4); top:var(--s2); }

/* ── C6 footer ────────────────────────────────────────────────────────────── */
/* Yale guidance makes the footer the one required home for the logo: lower
   left, with clear space, a copyright line with the year, and the university
   privacy policy. Reversed on Yale Blue is the default treatment. */
.foot{ background:var(--action); color:#fff; margin-top:var(--s7); }
.foot__in{ display:grid; gap:var(--s4); padding:var(--s5) 0 var(--s4); }
.foot__mark{ font-family:var(--serif); font-size:var(--fs-section); color:#fff;
  text-decoration:none; justify-self:start; }
.foot__cols{ display:grid; gap:var(--s4); }
.foot__col{ display:flex; flex-direction:column; align-items:flex-start; }
.foot__h{ font-size:var(--fs-label); letter-spacing:var(--track-label);
  text-transform:uppercase; color:rgba(255,255,255,.72); margin:0 0 var(--s2); }
/* Reversed white with a 50% hairline; hover raises the hairline to full white. */
.foot__col a{ color:#fff; text-decoration:none; font-size:var(--fs-meta);
  line-height:var(--lh-meta); padding:var(--s2) 0;
  border-bottom:1px solid rgba(255,255,255,.5); }
.foot__col a:hover{ border-bottom-color:#fff; }
.foot__col a:focus-visible{ outline:2px solid #fff; outline-offset:2px; }
.foot__signout{ background:none; border:0; padding:0; margin:0; cursor:pointer;
  font-family:inherit; font-size:var(--fs-meta); color:#fff; text-align:left;
  border-bottom:1px solid transparent; }
.foot__signout:hover{ border-bottom-color:#fff; }
.foot__signout:focus-visible{ outline:2px solid #fff; outline-offset:2px; }
.foot__legal{ margin:0; font-size:var(--fs-meta); line-height:var(--lh-meta);
  color:rgba(255,255,255,.82); }

/* Two short link columns fit long before 1024 — leaving them stacked until
   then made the footer one long list on most laptops. */
@media (min-width:560px){
  .foot__cols{ grid-template-columns:repeat(2, minmax(0,1fr)); gap:var(--s6); }
}
@media (min-width:1024px){
  /* The logo gets clear space to its right and nothing sits above or below it,
     so it holds the lower-left corner on its own row. */
  .foot__in{ grid-template-columns:auto 1fr; column-gap:var(--s7); align-items:start; }
  .foot__mark{ margin-right:var(--s7); }
  .foot__cols{ gap:var(--s7); }
  .foot__legal{ grid-column:1 / -1; }
}

/* ── F1  Masthead: the Vote pill dropped to a second line on phones ──────────
   .nav had flex-wrap:wrap and a 24px gap beside a 101px wordmark; at 390px
   the four items did not fit, so the pill wrapped under "Home". Below 560px
   the bar is one row, never two: nothing wraps, the gaps tighten, the pill
   loses 8px of padding. If a locale ever adds a fifth item the row scrolls
   sideways instead of breaking. */
.masthead__in{ flex-wrap:nowrap; }
.nav{ flex-wrap:nowrap; min-width:0; }
.nav a{ white-space:nowrap; }
@media (max-width:559px){
  .masthead__in{ gap:var(--s3); }
  .nav{ gap:var(--s3); overflow-x:auto; scrollbar-width:none; padding-bottom:0; }
  .nav::-webkit-scrollbar{ display:none; }
  .nav a{ font-size:14px; }
  .nav a.nav-vote, .nav a.nav-vote--clock{ padding:0 var(--s3); min-height:34px; height:34px; }
  .nav a.nav-vote--clock{ width:84px; }
