/* ============================================================
   BASE — element defaults. Everything visual comes from tokens.css.
   ============================================================ */

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

html {
  -webkit-text-size-adjust: 100%;
  /* The wall screen has no keyboard and no scrollbar; hiding the
     overscroll bounce keeps it from looking broken when someone
     drags it. */
  overscroll-behavior: none;
  /* The browser's own grey flash on tap fights the press feedback every
     control here already has. */
  -webkit-tap-highlight-color: transparent;
}

/* A pinned theme has to tell the browser too. Otherwise the kiosk pinned
   dark on a Pi whose OS says light draws its scrollbars and any native
   control light, on a dark page. */
:root[data-theme="light"] { color-scheme: light; }
:root[data-theme="dark"]  { color-scheme: dark; }

body {
  margin: 0;
  background: var(--bg-app);
  color: var(--text-body);
  font-family: var(--font-sans);
  font-size: var(--text-md);
  line-height: var(--lh-normal);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-synthesis: none;
}

h1, h2, h3 {
  margin: 0;
  color: var(--text-strong);
  font-weight: var(--fw-bold);
  line-height: var(--lh-snug);
}
/* A page's title is set in the display face, like the date: it is the one
   other thing on a screen that says where you are. */
h1 {
  font-family: var(--font-display);
  font-size: var(--text-2xl);
  font-weight: var(--fw-heavy);
  letter-spacing: var(--tracking-tight);
}
h2 { font-size: var(--text-xl); letter-spacing: var(--tracking-tight); }
h3 { font-size: var(--text-lg); }

p { margin: 0 0 var(--space-3); }
p:last-child { margin-bottom: 0; }

a { color: var(--accent); text-decoration: none; }
/* Every :hover in this system sits behind this query. A touch screen
   fakes hover on tap and leaves it stuck until the next tap elsewhere —
   on the wall panel that is a slot that stays highlighted after the
   person has walked away. */
@media (hover: hover) and (pointer: fine) {
  a:hover { color: var(--accent-hover); text-decoration: underline; }
}

button, input, select, textarea { font: inherit; color: inherit; }

/* A control never double-tap-zooms, so the tap fires at once; and a long
   press on one must not select its label. Content stays selectable. */
button, a, summary, [role="button"] { touch-action: manipulation; }
button, summary, [role="button"] {
  user-select: none;
  -webkit-user-select: none;
}

/* One focus ring, defined once. An outline follows the element's own
   corner radius and leaves its box-shadow alone. Zero specificity
   (:where), so a component can move it inside its own edge by setting
   --ring-gap below zero where a box around it clips. */
:where(:focus-visible) {
  outline: var(--ring-width) solid var(--ring-color);
  outline-offset: var(--ring-gap);
}

/* On what is pressed, the same ring is drawn on ::after so it can grow in:
   it settles from a little larger, so a keyboard user sees where they
   landed. Only transform and opacity move. The outline stays, transparent,
   for Windows high contrast, which draws it in its own colour. A field
   keeps the plain outline: it cannot carry a pseudo-element. Positioned
   only while focused and at zero specificity, so a control that places
   itself (the skip link) keeps its own position. */
:where(button, a[href], summary, [role="button"]):where(:focus-visible) {
  position: relative;
  outline-color: transparent;
}
:where(button, a[href], summary, [role="button"]):where(:focus-visible)::after {
  content: "";
  position: absolute;
  inset: calc(-1 * (var(--ring-gap) + var(--ring-width)));
  border: var(--ring-width) solid var(--ring-color);
  border-radius: inherit;
  pointer-events: none;
  transition:
    transform var(--dur-fast) var(--ease-out),
    opacity var(--dur-fast) var(--ease-out);
}
@starting-style {
  :where(button, a[href], summary, [role="button"]):where(:focus-visible)::after {
    transform: scale(1.06);
    opacity: 0;
  }
}
/* Reduced motion: it fades in where it ends up. */
@media (prefers-reduced-motion: reduce) {
  :where(button, a[href], summary, [role="button"]):where(:focus-visible)::after { transition-property: opacity; }
  @starting-style {
    :where(button, a[href], summary, [role="button"]):where(:focus-visible)::after { transform: none; }
  }
}

/* Times, dates and apartment numbers are compared down a column, so
   the digits have to line up. */
.tnum { font-variant-numeric: tabular-nums; }

.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* Skip link — the calendar is a long list, and a keyboard user should
   not have to tab through a week to reach the resource switcher. */
.skip-link {
  position: absolute;
  left: var(--space-3);
  top: calc(-1 * var(--space-7));
  z-index: var(--z-skip);
  padding: var(--space-2) var(--space-4);
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  /* No transition. It only ever appears from the keyboard, and a
     keyboard action that animates feels like the page is lagging. */
}
.skip-link:focus { top: var(--space-3); }

/* Keyframes are for motion that never stops. Anything that enters or
   leaves uses a transition instead (see components.css), because a
   transition can be interrupted and a keyframe restarts from zero. */
@keyframes ssb-shimmer { to { background-position: -200% 0; } }
@keyframes ssb-spin    { to { transform: rotate(360deg); } }
@keyframes ssb-pulse   { 0%, 100% { opacity: 1; } 50% { opacity: 0.25; } }

/* Reduced motion means gentler, not none: movement goes, fades and
   colour stay, because they are what makes a change legible. Each
   component that moves says how it behaves under
   `prefers-reduced-motion`, next to its own rule. The press scale is
   kept: it is feedback, three per cent, and on a touch screen it is the
   only sign the tap landed. */
