/* ==========================================================================
   OTN theme: base layer (DESIGN.md 6.0 and section 5), ported from the
   mockups' assets/css/base.css.
   Loads after tokens.css and theme-light.css, before components.css.

   Element rules are written ":root :where(...)": one class's weight, so
   they beat WordPress's own layout resets (also one class's weight, and
   printed earlier) while any component class still overrides them.
   Utilities (DESIGN.md 12.2): otn-visually-hidden, otn-container(--reading
   |--max), otn-section(--raised|--screen|--tight), otn-on-raised,
   otn-actions. The skip link (6.2) lives here too: every page has it.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Reset
   -------------------------------------------------------------------------- */

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

/* Components set their own display values; [hidden] must still win
   (the light/dark switch before theme.js runs, the "On now" lines, notices). */
[hidden] {
  display: none !important;
}

/* --------------------------------------------------------------------------
   Page (6.0)
   -------------------------------------------------------------------------- */

/* scroll-padding-bottom: focus scrolling keeps the focused item above the
   fixed cookie notice (WCAG technique C43). color-scheme comes with the
   colour tokens (tokens.css, theme-light.css). */
html {
  background-color: var(--otn-bg);
  color: var(--otn-text);
  font-synthesis: none;
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  scroll-padding-bottom: var(--otn-cookie-h);
}

@media (prefers-reduced-motion: no-preference) {
  html {
    scroll-behavior: smooth;
  }
}

/* Same condition as the sticky header (6.5), so the padding is only there
   when the header actually sticks. */
@media (min-width: 900px) and (min-height: 500px) {
  html {
    scroll-padding-top: var(--otn-scroll-pad);
  }
}

body {
  margin: 0;
  padding-bottom: var(--otn-cookie-h);
  background-color: var(--otn-bg);
  color: var(--otn-text);
  font: var(--otn-fw-book) var(--otn-fs-body)/var(--otn-lh-body) var(--otn-font-sans);
  overflow-wrap: break-word;
}

/* --------------------------------------------------------------------------
   Typography (section 5)
   Display sizes, leads, quotes, labels and numerals are applied by the
   component classes in components.css; these are the element defaults.
   -------------------------------------------------------------------------- */

:root :where(h1, h2, h3, h4, h5, h6, p, figure, blockquote, dl, dd) {
  margin: 0;
}

:root :where(p) {
  margin-block: 0 1em;
  max-width: var(--otn-measure);
  text-wrap: pretty;
}

:root :where(p:last-child) {
  margin-bottom: 0;
}

/* H1 and H2: Syracuse Block Condensed 700, capitals from CSS only */
:root :where(h1, h2) {
  font-family: var(--otn-font-display);
  font-weight: var(--otn-fw-display);
  text-transform: uppercase;
}

:root :where(h1) {
  font-size: var(--otn-fs-display-l);
  line-height: var(--otn-lh-display);
  letter-spacing: var(--otn-ls-display);
}

:root :where(h2) {
  font-size: var(--otn-fs-display-m);
  line-height: var(--otn-lh-heading);
  letter-spacing: var(--otn-ls-heading);
}

/* H3 and H4: Sherman Sans Bold, as written */
:root :where(h3, h4, h5, h6) {
  font-family: var(--otn-font-sans);
  font-weight: var(--otn-fw-bold);
  text-transform: none;
}

:root :where(h3) {
  font-size: var(--otn-fs-h3);
  line-height: var(--otn-lh-h3);
}

:root :where(h4, h5, h6) {
  font-size: var(--otn-fs-h4);
  line-height: 1.3;
}

/* Headings wrap, never overflow (fallback fonts are much wider) */
:root :where(h1, h2, h3) {
  text-wrap: balance;
}

:root :where(h1, h2, h3, h4, h5, h6) {
  overflow-wrap: break-word;
}

:where(strong, b) {
  font-weight: var(--otn-fw-bold);
}

/* Italic only for <em> (and the RTNDA sentence, which is an <em>) */
:where(em, i) {
  font-style: italic;
}

:where(small) {
  font-size: var(--otn-fs-small);
  line-height: var(--otn-lh-small);
}

:where(address) {
  font-style: normal;
}

/* An empty text block (a box OTN hasn't filled in yet, such as the Contact
   page's introduction) prints nothing visible */
:where(main) :is(p, h1, h2, h3, h4):empty {
  display: none;
}

/* --------------------------------------------------------------------------
   Links (6.0): always underlined. Dark mode Light Orange, white on hover;
   light mode Dark Orange #D74100, navy on hover (the --otn-link tokens).
   Buttons that are links (.wp-element-button) draw their own colours.
   -------------------------------------------------------------------------- */

:root :where(a:not(.wp-element-button)) {
  color: var(--otn-link);
  text-decoration: underline;
  text-decoration-thickness: 2px;
  text-underline-offset: 0.18em;
}

:root :where(a:not(.wp-element-button):hover) {
  color: var(--otn-link-hover);
}

/* --------------------------------------------------------------------------
   Focus (6.0): a 3px ring in --otn-focus (white on dark surfaces, navy on
   light pages; white again inside the dark parts), outline (not
   box-shadow) so it survives forced-colours mode. Components only change
   the offset, or add a halo where the ring crosses two surfaces.
   -------------------------------------------------------------------------- */

:focus-visible {
  outline: var(--otn-focus-width) solid var(--otn-focus);
  outline-offset: var(--otn-focus-offset);
}

/* <main> only receives focus from the skip link and "Back to top" */
main:focus {
  outline: none;
}

/* Back to top and the skip link go to #main. On phones (and wherever the
   header doesn't stick) the jump stops 8rem short (more than the LIVE bar
   plus the 64px header row, even when the LIVE bar wraps at 320px); the
   browser clamps at the page top, so the LIVE bar, logo and Menu are in
   view. Focus still moves to <main>. */
#main {
  scroll-margin-top: 8rem;
}

/* Same condition as the sticky header (6.5): the sticky header's
   scroll-padding-top does it here. After the rule above, so it wins. */
@media (min-width: 900px) and (min-height: 500px) {
  #main {
    scroll-margin-top: 0;
  }
}

/* --------------------------------------------------------------------------
   Images and media (6.0). Image blocks get their width and height from
   WordPress (prevents layout shift).
   -------------------------------------------------------------------------- */

img {
  max-width: 100%;
  height: auto;
  display: block;
}

svg {
  fill: currentColor;
}

iframe {
  border: 0;
}

/* --------------------------------------------------------------------------
   Lists that are visual groups carry role="list" (Safari drops list
   semantics when list-style is none), so the reset keys on that. The
   theme adds role="list" to its own lists (inc/markup.php).
   -------------------------------------------------------------------------- */

:root :where(ul[role="list"], ol[role="list"]) {
  list-style: none;
  margin: 0;
  padding: 0;
}

/* --------------------------------------------------------------------------
   Forms and tables
   -------------------------------------------------------------------------- */

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

:where(button, summary) {
  cursor: pointer;
}

:where(table) {
  border-collapse: collapse;
}

/* --------------------------------------------------------------------------
   Utilities (6.0, 12.2)
   -------------------------------------------------------------------------- */

.otn-visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  border: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.otn-container {
  max-width: var(--otn-w-wide);
  margin-inline: auto;
  padding-inline: var(--otn-gutter);
}

.otn-container--reading {
  max-width: calc(var(--otn-w-reading) + 2 * var(--otn-gutter));
}

.otn-container--max {
  max-width: var(--otn-w-max);
}

.otn-section {
  padding-block: var(--otn-section-y);
}

/* #203299 band; the markup also adds .otn-on-raised (the rules below
   accept either class, so a band is never left with orange links) */
.otn-section--raised {
  background-color: var(--otn-raised);
}

/* Black: media only, never behind our text */
.otn-section--screen {
  background-color: var(--otn-screen);
}

.otn-section--tight {
  padding-block: calc(var(--otn-section-y) / 2);
}

/* On #203299 surfaces every word is white, links included (underlined).
   Buttons keep their own colours (navy on orange). In light mode these
   surfaces are white (--otn-raised), so the text is navy and the links
   Dark Orange (--otn-link-on-raised); the LIVE bar and cookie notice stay
   #203299 with white text (dark parts, tokens.css). */
:is(.otn-on-raised, .otn-section--raised) {
  color: var(--otn-text);
}

:is(.otn-on-raised, .otn-section--raised) a:not(.otn-btn, .wp-element-button) {
  color: var(--otn-link-on-raised);
}

/* Button groups (6.8): full width below 480px, in source order (primary
   first), side by side from 480px. Works on the mockups' <a> buttons and
   on core/buttons (whose items are .wp-block-button). */
.otn-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--otn-space-3);
}

.otn-actions > * {
  flex: 1 1 100%;
}

@media (min-width: 480px) {
  .otn-actions > * {
    flex: 0 1 auto;
  }
}

/* --------------------------------------------------------------------------
   6.2 Skip link (printed by the theme: inc/setup.php)
   Off-screen until focused; orange fill, navy Sherman Sans Bold 16px.
   -------------------------------------------------------------------------- */

.otn-skip {
  position: absolute;
  top: 0;
  left: 0;
  z-index: var(--otn-z-skip);
  transform: translateY(-200%);
  padding: var(--otn-space-3) var(--otn-space-4);
  background-color: var(--otn-accent);
  color: var(--otn-text-on-accent);
  font-family: var(--otn-font-sans);
  font-size: 1rem;
  font-weight: var(--otn-fw-bold);
  line-height: var(--otn-lh-label);
  text-decoration: none;
  border-radius: var(--otn-radius-s);
}

.otn-skip:hover {
  color: var(--otn-text-on-accent);
}

.otn-skip:focus {
  position: fixed;
  top: var(--otn-space-2);
  left: var(--otn-space-2);
  transform: none;
}

/* Light mode: the skip link shows over the #203299 LIVE bar and the white
   header at once, so its navy ring gets a white halo (ring vs halo
   17.63:1, halo vs LIVE bar 10.62:1). Dark mode: the halo is transparent. */
.otn-skip:focus-visible {
  box-shadow: 0 0 0 calc(var(--otn-focus-offset) + 2 * var(--otn-focus-width)) var(--otn-skip-halo);
}

/* Logged-in visitors: WordPress's toolbar sits over the top 32px (46px on
   phones), so the focused skip link moves under it */
.admin-bar .otn-skip:focus {
  top: calc(32px + var(--otn-space-2));
}

@media (max-width: 782px) {
  .admin-bar .otn-skip:focus {
    top: calc(46px + var(--otn-space-2));
  }
}

/* --------------------------------------------------------------------------
   Forced colours (Windows High Contrast): global rules.
   Component rules (straps, badges, chips, tiles, bars drawn with
   backgrounds) sit at the end of each component in components.css.
   -------------------------------------------------------------------------- */

@media (forced-colors: active) {
  :focus-visible {
    outline-color: Highlight;
  }

  svg {
    fill: currentColor;
  }

  .otn-skip {
    border: 1px solid CanvasText;
  }
}
