/* ==========================================================================
   Opleague — shared page parts
   --------------------------------------------------------------------------
   Built from the Figma mockup, Q53m705DcCXQlGQr8ibfCl. Sizes and colors here
   are measured from that file, not chosen here. Tokens load first; if a
   var() below resolves to nothing, functions.php has enqueued out of order.

   Sections:
     1. Base and layout
     2. Type
     3. The fading light
     4. Nav
     5. Buttons
     6. Footer
   ========================================================================== */


/* 1. Base and layout ------------------------------------------------------ */

/* The page reset.
   This lived in WordPress's global-styles block, which every page was
   loading as 9KB of inline CSS for a site that uses no blocks at all. That
   CSS is now dropped, and it took ":where(body){margin:0}" with it, which
   would have left the browser's default 8px gutter around every page.
   A theme should never have been depending on the block editor's stylesheet
   for its own reset, so the reset lives here now where it belongs. */
/* Border-box everywhere.
   This was missing, and it was the single biggest layout bug on the site.
   .opl-wrap is width:100% with padding-inline, so under content-box it
   rendered a full gutter wider than its parent: 422px inside a 390px phone.
   Buttons and form fields did the same. On a desktop it is invisible, because
   the wrap is capped well inside a wide window, so it only showed up below
   about 1030px, which is every phone and most tablets. Every page overflowed
   to the right and nobody could see it on the machine it was built on.
   Found 2026-09-19 by measuring every element against the viewport at 390px. */
*,
*::before,
*::after {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  padding: 0;
}

/* A floor for long unbreakable strings. Nothing on the site needs it today,
   the longest visible word across every page is under 24 characters, but
   player names, pasted links and network IDs are all coming with accounts,
   and a single long token is enough to push a phone layout sideways. This
   only does anything when a word would otherwise overflow. */
body {
  overflow-wrap: break-word;
}


.opl body,
body.opl {
  background: var(--opl-page) fixed;
  color: var(--opl-slate);
  font-family: var(--opl-font-body);
  font-size: var(--opl-size-body);
  line-height: var(--opl-line-body);
  -webkit-font-smoothing: antialiased;
}

/* The standard content column, and the two variants the mockup uses. */
.opl-wrap        { width: 100%; max-width: var(--opl-content);      margin-inline: auto; padding-inline: var(--opl-gutter); }
.opl-wrap--wide  { max-width: var(--opl-content-wide); }
.opl-wrap--read  { max-width: var(--opl-content-read); }

/* A full-bleed band. Dark ones carry a glow, so they need a stacking
   context and hidden overflow or the blur spills onto the next section. */
.opl-band {
  position: relative;
  overflow: hidden;
  padding-block: var(--opl-s10);
}
.opl-band--dark      { background: var(--opl-blue-800); color: var(--opl-white); }
.opl-band--dark-mid  { background: var(--opl-blue-600); color: var(--opl-white); }
.opl-band--light     { background: var(--opl-white);    color: var(--opl-slate); }
.opl-band--paper     { background: var(--opl-paper);    color: var(--opl-slate); }
.opl-band--accent    { background: var(--opl-accent);   color: var(--opl-white); }

/* Content has to sit above the glow. */
.opl-band > *:not(.opl-glow) { position: relative; z-index: 1; }


/* 2. Type ----------------------------------------------------------------- */

.opl h1, .opl h2, .opl h3, .opl h4,
.opl-display, .opl-title {
  font-family: var(--opl-font-head);
  font-weight: 700;
  line-height: var(--opl-line-tight);
  color: inherit;
  margin: 0;
}

/* The wide-tracked page titles. OPLEAGUE, THE GAMES, LEADERBOARD. */
.opl-display {
  font-size: var(--opl-size-hero);
  letter-spacing: var(--opl-track-display);
  text-transform: uppercase;
}
.opl-title   { font-size: var(--opl-size-h1); letter-spacing: 3px; text-transform: uppercase; }
.opl-h2      { font-size: var(--opl-size-h2); }
.opl-h3      { font-size: var(--opl-size-h3); }

/* The small-caps label above a heading. Accent on light. */
.opl-eyebrow {
  font-family: var(--opl-font-head);
  font-weight: 700;
  font-size: var(--opl-size-eyebrow);
  letter-spacing: var(--opl-track-eyebrow);
  text-transform: uppercase;
  color: var(--opl-accent);
  display: block;
}
/* On a dark ground the accent is too dark to read, so it lifts. */
.opl-band--dark .opl-eyebrow,
.opl-band--dark-mid .opl-eyebrow { color: var(--opl-accent-lift); }
/* Except where the mockup calls for the brand orange. */
.opl-eyebrow--ember { color: var(--opl-ember); }

/* The band rules above are two classes deep, so they beat a one-class
   modifier and the ember eyebrow silently came out blue on every dark band.
   Mike asked for NEVER GIVE UP ON YOUR OLD DREAMS in the brand orange, and
   this is what makes it stick. Any future --ember modifier needs the same
   treatment: a modifier has to outrank the band default, not tie with it. */
.opl-band--dark .opl-eyebrow--ember,
.opl-band--dark-mid .opl-eyebrow--ember,
.opl-band--accent .opl-eyebrow--ember { color: var(--opl-ember); }

/* The supporting line under a big heading.
   RULE: on a dark band this is WHITE, the same as its heading, so it carries.
   Muting it there was the bug Mike caught on the 404 page. */
.opl-lede {
  font-family: var(--opl-font-body);
  font-weight: 300;
  font-size: var(--opl-size-lede);
  line-height: 1.5;
  color: var(--opl-steel);
}
.opl-band--dark .opl-lede,
.opl-band--dark-mid .opl-lede,
.opl-band--accent .opl-lede { color: var(--opl-white); }

/* The short accent rule under a section heading. 40x2 in the mockup. */
.opl-rule { display: block; width: 40px; height: 2px; background: var(--opl-accent); border: 0; margin: var(--opl-s3) 0 0; }
.opl-band--dark .opl-rule { background: var(--opl-accent-lift); }

.opl-meta { font-size: var(--opl-size-meta); color: var(--opl-gray); }


/* 3. The fading light ----------------------------------------------------- */
/* One soft blurred light per dark band, in six variations so no two adjacent
   pages match. The light deliberately hangs off the edge: only the falloff
   should be visible, never the shape of the ellipse. */

.opl-glow {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  z-index: 0;
}
.opl-glow__light,
.opl-glow__core {
  position: absolute;
  display: block;
  border-radius: 50%;
  filter: blur(var(--opl-glow-blur));
}
.opl-glow__light { background: var(--opl-glow-color); opacity: var(--opl-glow-opacity); }
.opl-glow__core  { background: var(--opl-glow-core);  opacity: 0.30; filter: blur(70px); }

/* dawn — wide light, low and to the left */
.opl-glow--dawn  .opl-glow__light { width: 55%; height: 160%; left: -12%; top: -30%; }
/* dusk — the same, mirrored */
.opl-glow--dusk  .opl-glow__light { width: 55%; height: 160%; left:  57%; top: -30%; }
/* crown — wide and shallow off the top, with a bright core */
.opl-glow--crown .opl-glow__light { width: 70%; height: 110%; left:  15%; top: -55%; opacity: 0.34; }
.opl-glow--crown .opl-glow__core  { width: 18%; height:  50%; left:  41%; top: -15%; }
/* rise — a big light from below */
.opl-glow--rise  .opl-glow__light { width: 85%; height: 120%; left: 7.5%; top:  55%; opacity: 0.30; }
/* drift — two lights, opposite corners */
.opl-glow--drift .opl-glow__light { width: 45%; height: 120%; left:  -8%; top: -20%; opacity: 0.28; }
.opl-glow--drift .opl-glow__core  { width: 30%; height:  80%; left:  72%; top:  30%; background: var(--opl-accent-deep); opacity: 0.26; filter: blur(100px); }
/* spark — tight light upper right, plus a core */
.opl-glow--spark .opl-glow__light { width: 38%; height: 100%; left:  62%; top: -25%; opacity: 0.34; filter: blur(110px); }
.opl-glow--spark .opl-glow__core  { width: 10%; height:  28%; left:  76%; top:   5%; opacity: 0.34; filter: blur(55px); }
/* hearth — the footer's own. White, not blue, or it tints the gray. */
.opl-glow--hearth .opl-glow__light {
  width: 92%; height: 85%; left: 4%; top: 70%;
  background: var(--opl-white);
  opacity: var(--opl-glow-footer);
  filter: blur(160px);
}

/* The star field. Only on bands 240px and taller, or it reads as dust. */
.opl-glow--stars::after {
  content: "";
  position: absolute;
  inset: 0;
  background-image:
    radial-gradient(1px 1px at 12% 22%, rgba(255,255,255,.45) 50%, transparent 50%),
    radial-gradient(1px 1px at 31% 64%, rgba(255,255,255,.30) 50%, transparent 50%),
    radial-gradient(2px 2px at 48% 18%, rgba(255,255,255,.38) 50%, transparent 50%),
    radial-gradient(1px 1px at 63% 77%, rgba(255,255,255,.42) 50%, transparent 50%),
    radial-gradient(1px 1px at 79% 34%, rgba(255,255,255,.28) 50%, transparent 50%),
    radial-gradient(1px 1px at 88% 59%, rgba(255,255,255,.36) 50%, transparent 50%),
    radial-gradient(1px 1px at 22% 82%, rgba(255,255,255,.26) 50%, transparent 50%),
    radial-gradient(2px 2px at 55% 45%, rgba(255,255,255,.22) 50%, transparent 50%);
}


/* 4. Nav ------------------------------------------------------------------ */

.opl-nav {
  background: var(--opl-blue-600);
  color: var(--opl-white);
  min-height: 80px;
  display: flex;
  align-items: center;
}
.opl-nav__inner {
  width: 100%;
  max-width: var(--opl-content-wide);
  margin-inline: auto;
  padding-inline: var(--opl-s8);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--opl-s6);
}

/* Brand: the OPLG mark sits to the LEFT of the wordmark. */
.opl-brand { display: flex; align-items: center; gap: 14px; text-decoration: none; color: inherit; }
.opl-brand__word {
  font-family: var(--opl-font-head);
  font-weight: 700;
  font-size: var(--opl-size-h3);
  letter-spacing: 4px;
  text-transform: uppercase;
  color: currentColor;
  white-space: nowrap;
}

/* The mark. "GET SOME." is dropped at this size because it is illegible
   below about 10px; the full lockup with it lives in the hero. */
.opl-mark {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 5px 7px;
  border: 2px solid currentColor;
  line-height: 1;
  flex: none;
}
.opl-mark span {
  font-family: var(--opl-font-head);
  font-weight: 700;
  font-size: 13px;
  letter-spacing: 0.5px;
}

.opl-nav__menu { display: flex; align-items: center; gap: 36px; margin: 0; padding: 0; list-style: none; }
.opl-nav__menu a {
  font-family: var(--opl-font-head);
  font-weight: 500;
  font-size: 12px;
  letter-spacing: 0.6px;
  text-transform: uppercase;
  color: var(--opl-white);
  text-decoration: none;
}
.opl-nav__menu a:hover,
.opl-nav__menu a:focus-visible { color: var(--opl-accent-halo); }

/* ---------------------------------------------------------------- sub-nav
 * Three groups in the bar, each opening the section beneath it. The same
 * architecture the footer prints, so the top of the page and the bottom
 * describe the same site.
 *
 * NO JAVASCRIPT. It opens on :hover for a mouse and on :focus-within for a
 * keyboard, which means tabbing through the bar reveals each panel in turn
 * with nothing to initialise and nothing to break. A script here would be a
 * third thing that has to agree with the other two.
 *
 * The parent stays a real link. On a touch screen a heading that only opens
 * a panel is a trap: there is no hover to leave, so the first tap has to go
 * somewhere. It goes to the section's own page.
 */
.opl-nav__group { position: relative; }

.opl-nav__sub {
  position: absolute;
  top: 100%;
  left: -14px;
  z-index: 40;
  min-width: 210px;
  margin: 0;
  padding: 10px 0;
  list-style: none;
  background: var(--opl-blue-700);
  border: 1px solid var(--opl-blue-300);
  border-radius: 4px;
  box-shadow: var(--opl-shadow-over);

  /* Hidden from sight AND from the keyboard, but still measurable, so the
     panel does not change size the first time it opens. */
  visibility: hidden;
  opacity: 0;
  transform: translateY(-4px);
  transition: opacity 0.14s ease, transform 0.14s ease, visibility 0s linear 0.14s;
}

.opl-nav__group:hover > .opl-nav__sub,
.opl-nav__group:focus-within > .opl-nav__sub {
  visibility: visible;
  opacity: 1;
  transform: translateY(0);
  transition-delay: 0s;
}

/*
 * A forgiving bridge between the heading and the panel. Without it the
 * four pixels of gap under the heading close the menu while the pointer is
 * still travelling to it, which reads as the menu flickering shut on you.
 */
.opl-nav__group::after {
  content: "";
  position: absolute;
  inset: 100% -14px auto;
  height: 12px;
}

.opl-nav__sub a {
  display: block;
  padding: 9px 18px;
  font-size: 12px;
  letter-spacing: 0.4px;
  text-transform: none;
  white-space: nowrap;
}
/*
 * EMBER ON HOVER, not the pale blue. Mike, 2026-09-20.
 *
 * The sub-nav was using --opl-accent-halo, the same cool blue as every
 * other link on a dark ground, which made the one genuinely interactive
 * moment in the bar look identical to ordinary text. Ember is the brand's
 * only warm note and it is what the site uses everywhere else to say "this
 * is the thing to press".
 *
 * :focus-visible gets it too, so a keyboard user sees exactly what a mouse
 * user sees. Those two drifting apart is how a site ends up keyboard
 * accessible in theory.
 */
.opl-nav__sub a:hover,
.opl-nav__sub a:focus-visible {
  background: var(--opl-blue-600);
  color: var(--opl-ember);
}

/* The group headings in the bar itself, for the same reason. */
.opl-nav__menu a:hover,
.opl-nav__menu a:focus-visible { color: var(--opl-ember); }

/* The heading reads as a heading, not as one more item in a row of ten. */
.opl-nav__top { font-weight: 700; }

/*
 * The menu button. Measured at 360px on 2026-09-19 it was 28x33, because
 * it set padding and nothing else: a <button> with no font-size inherits
 * the browser default of about 13px, so the burger glyph was tiny and the
 * box around it followed.
 *
 * On a phone this is THE navigation control, and every touch guideline
 * asks for around 44px square. min-width and min-height do that without
 * changing the layout, since the row is already 40px tall for the mark.
 */
.opl-nav__toggle {
  display: none;
  background: none;
  border: 0;
  color: inherit;
  padding: var(--opl-s2);
  cursor: pointer;
  font-size: 22px;
  line-height: 1;
  min-width: 44px;
  min-height: 44px;
  align-items: center;
  justify-content: center;
}


/* 5. Buttons -------------------------------------------------------------- */
/* The rule that matters: a solid blue button on a dark blue ground vanishes,
   so on dark it becomes ember. That is the only job ember has. */

.opl-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--opl-s2);
  font-family: var(--opl-font-head);
  font-weight: 700;
  font-size: var(--opl-size-eyebrow);
  letter-spacing: var(--opl-track-label);
  text-transform: uppercase;
  text-decoration: none;
  padding: 15px 24px;
  /* 15px of padding either side of a 12px cap height lands on 42, two short
     of the 44px Apple and WCAG both point at for something you tap with a
     thumb. min-height lifts it without touching the padding, so nothing
     moves visually. The nav toggle above and the signup button already use
     44; this makes every button agree with them. Measured 2026-09-19. */
  min-height: 44px;
  border: 1px solid transparent;
  border-radius: var(--opl-radius);
  cursor: pointer;
  transition: background-color .15s ease, border-color .15s ease, color .15s ease;
}

/*
 * The filled button is the loudest thing on most bands, so it gets the
 * elevation to match and lifts under the pointer. Outline and ghost
 * deliberately stay flat: three raised buttons in one row is three things
 * shouting, and the hierarchy set in the bar would be lost.
 */
.opl-btn--primary {
  background: var(--opl-accent);
  color: var(--opl-white);
  box-shadow: var(--opl-shadow-card);
  transition: background 140ms ease, box-shadow 140ms ease, transform 140ms ease;
}
.opl-btn--primary:hover {
  background: var(--opl-accent-mid);
  color: var(--opl-white);
  box-shadow: var(--opl-shadow-lift);
  transform: translateY(-1px);
}

.opl-btn--ember  { background: var(--opl-ember); color: var(--opl-ember-ink); }
.opl-btn--ember:hover { background: #CF4F22; }  /* darker again: the ink is white now, so the logic inverts */
/* The hover had to move back with the ink. A LIGHTER hover helps dark
   text and hurts white: #EE6B39 gives white only 3.09, while the older
   darker #CF4F22 gives it 4.38. Same reasoning Mike used to pick the
   lighter one, run the other way. */

.opl-btn--outline { background: transparent; border-color: currentColor; color: inherit; }
.opl-btn--outline:hover { background: rgba(255,255,255,.08); }

/*
 * A button with no box. For the quietest action in a row of them.
 *
 * The bar now ends with up to three: sign in, sign up, join a tournament.
 * Three equally loud buttons is no hierarchy at all, and the one that
 * matters is the tournament. So the CTA keeps the ember fill, signing up
 * gets an outline, and signing in is text, which is the right weight for
 * something only returning members look for.
 *
 * Still a real button underneath, so it keeps the 44px minimum height the
 * rest of them were given for thumbs.
 */
.opl-btn--ghost { background: transparent; border-color: transparent; color: inherit; }
.opl-btn--ghost:hover { background: rgba(255,255,255,.10); }

/* The right-hand end of the bar. */
.opl-nav__actions { display: flex; align-items: center; gap: var(--opl-s3); flex: none; }

.opl-btn--ink   { background: var(--opl-blue-800); color: var(--opl-white); }
.opl-btn--quiet { background: transparent; color: var(--opl-accent); padding-inline: 0; }

/* The automatic version of the rule: inside a dark band, a primary button
   becomes ember without anyone having to remember to change the class. */
.opl-band--dark .opl-btn--primary,
.opl-band--dark-mid .opl-btn--primary,
.opl-nav .opl-btn--primary { background: var(--opl-ember); color: var(--opl-ember-ink); }

.opl-btn:focus-visible { outline: 2px solid var(--opl-accent-halo); outline-offset: 2px; }


/* 6. Footer --------------------------------------------------------------- */
/* The footer is the Phoenix theme's own dark gray, NOT the site's blue ramp.
   Its glow is white rather than accent, because a blue light on gray tints
   the gray and undoes the point of using gray at all. */

.opl-footer {
  position: relative;
  overflow: hidden;
  background: var(--opl-footer-bg);
  color: var(--opl-footer-text);
  padding: 64px var(--opl-s8) 40px;
  font-size: var(--opl-size-meta);
}
.opl-footer__inner {
  position: relative;
  z-index: 1;
  max-width: var(--opl-content-wide);
  margin-inline: auto;
  display: flex;
  flex-direction: column;
  gap: var(--opl-s8);
}
.opl-footer hr,
.opl-footer__rule { border: 0; height: 1px; background: var(--opl-footer-rule); margin: 0; }

/* The Brevo signup row, above the columns. */
.opl-signup { display: flex; align-items: center; justify-content: space-between; gap: 60px; flex-wrap: wrap; }
.opl-signup__copy { display: flex; flex-direction: column; gap: var(--opl-s2); max-width: 520px; }
.opl-signup__title {
  font-family: var(--opl-font-head);
  font-weight: 700;
  font-size: var(--opl-size-meta);
  letter-spacing: var(--opl-track-label);
  text-transform: uppercase;
  color: var(--opl-white);
}
.opl-signup__form { display: flex; align-items: center; gap: var(--opl-s2); flex-wrap: wrap; }
.opl-signup__form input[type="text"],
.opl-signup__form input[type="email"] {
  height: 44px;
  padding: 0 14px;
  border: 0;
  background: var(--opl-footer-rule);
  color: var(--opl-white);
  font-family: var(--opl-font-body);
  font-size: var(--opl-size-meta);
}
.opl-signup__form input::placeholder { color: var(--opl-footer-text); }
.opl-signup__form input[name="opl_fname"] { width: 150px; }
.opl-signup__form input[name="opl_email"] { width: 210px; }
.opl-signup__form .opl-btn { height: 44px; padding-block: 0; }
.opl-signup__note { font-size: var(--opl-size-label); color: var(--opl-footer-muted); }

/* The honeypot. Never shown, never announced, and NOT display:none, because
   a hidden-field trap that a password manager fills eats real signups.
   See the fleet note on the Primary Ventures incident before changing this. */
.opl-hp {
  position: absolute !important;
  left: -9999px !important;
  width: 1px; height: 1px;
  overflow: hidden;
}

.opl-footer__columns { display: flex; gap: 64px; flex-wrap: wrap; }
.opl-footer__brand { flex: 1 1 320px; max-width: 360px; display: flex; flex-direction: column; gap: var(--opl-s3); }
.opl-footer__brand .opl-brand__word { font-size: var(--opl-size-h4); color: var(--opl-white); }
.opl-footer__address { font-size: var(--opl-size-label); color: var(--opl-footer-muted); }

.opl-footer__col { flex: 0 1 auto; min-width: 140px; }
.opl-footer__col h2 {
  font-family: var(--opl-font-head);
  font-weight: 600;
  font-size: var(--opl-size-label);
  letter-spacing: var(--opl-track-label);
  text-transform: uppercase;
  color: var(--opl-white);
  margin: 0 0 var(--opl-s4);
}
.opl-footer__col ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--opl-s3); }
/* Lighter than the body text so the links stand out, but deliberately not
   white. Mike asked for exactly this. */
.opl-footer__col a { color: var(--opl-footer-link); text-decoration: none; }
.opl-footer__col a:hover { color: var(--opl-white); }

/* The bottom band is a column of two things: the copyright row, then the
   trademark line. Keeping them in one wrapping row is what let the
   trademark line land beside the copyright instead of under it. */
.opl-footer__bottom { display: flex; flex-direction: column; align-items: flex-start; gap: var(--opl-s5); }
.opl-footer__row { display: flex; align-items: center; justify-content: space-between; gap: var(--opl-s5); flex-wrap: wrap; width: 100%; }
/* Legal links sit on one line beside the copyright, divided by pipes, the
   same shape Wolven Industries uses. */
.opl-legal { display: flex; align-items: center; gap: var(--opl-s3); font-size: 12px; }
.opl-legal a { color: var(--opl-footer-link); text-decoration: none; }
.opl-legal a:hover { color: var(--opl-white); }
.opl-legal__sep { color: #6E6E6E; }

/* Whose games these are. Quiet, full width, under the legal row. */
/*
 * Sits on its own line under the copyright, close to it.
 *
 * Mike, 2026-09-19: "this text appears to be on a linebreak too far away
 * from the copyright text."
 *
 * No flex-basis here, deliberately. It used to carry flex-basis:100% to
 * force its own line, which never worked: max-width:78ch clamps the
 * hypothetical main size BEFORE flex line-breaking, so the browser saw
 * 490px, found it fit next to the 652px copyright in a 1280px row, and
 * put the two side by side. Measured, not guessed: the two boxes
 * overlapped by 27px.
 *
 * It sits on its own line now because .opl-footer__bottom is a column,
 * so the line break is structural. margin 0 leaves only that column's
 * 20px gap, the spacing the rest of the footer already uses.
 *
 * 78ch keeps it readable. A 12px line running the full 1280px is a
 * worse read than a measured one, and nothing depends on its width.
 */
.opl-footer__trademarks {
  margin: 0;
  font-size: var(--opl-size-label);
  line-height: 1.6;
  color: var(--opl-gray);
  max-width: 78ch;
}
.opl-footer__trademarks a { color: var(--opl-footer-link); text-decoration: none; white-space: nowrap; }
.opl-footer__trademarks a:hover { color: var(--opl-white); }

.opl-social { display: flex; gap: var(--opl-s2); }
.opl-social a {
  width: 28px; height: 28px;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--opl-footer-rule);
  color: var(--opl-footer-link);
  font-family: var(--opl-font-head);
  font-weight: 700;
  font-size: var(--opl-size-micro);
  text-decoration: none;
}
.opl-social a:hover { border-color: var(--opl-footer-link); color: var(--opl-white); }


/* Responsive -------------------------------------------------------------- */
/* Breakpoints live in responsive.css, which is enqueued after this file.
   Keeping them in one place means "why is this wrong on a phone" has a
   single file to open. Do not add media queries here. */


/* The quiet end-of-section link. Same contrast rule as the buttons: a blue
   link on a blue ground is unreadable, so on the dark bands it goes ember. */
.opl-more { color: var(--opl-accent); }
.opl-band--dark .opl-more,
.opl-band--dark-mid .opl-more,
.opl-band--accent .opl-more { color: var(--opl-ember); }
.opl-more:hover,
.opl-more:focus-visible { text-decoration: underline; }


/* 22. Keyboard access ----------------------------------------------------
   Found by auditing the live page rather than reading the markup.
   ========================================================================== */

/*
 * The skip link was already first in the document and its target exists, and
 * WordPress's own CSS hides it off screen. What was missing everywhere was a
 * :focus rule, so a keyboard user tabbing onto it never saw it. The link
 * worked if you pressed Enter blindly, which is not the same as working.
 *
 * This is the standard pattern: pull it back on screen the moment it takes
 * focus, styled like the rest of the site rather than like a browser default.
 */
/*
 * THE BASE RULE, MISSING UNTIL 2026-09-20, AND IT WAS VISIBLE ON EVERY PAGE.
 *
 * The comment above says "WordPress's own CSS hides it off screen". That is
 * wrong, and it is the kind of wrong that survives because it sounds right:
 * core ships .screen-reader-text for the ADMIN, not the front end. Themes
 * define it themselves, which is why it lives in the underscores starter
 * theme rather than in WordPress.
 *
 * So the :focus rule below was written to reveal something that had never
 * been hidden. The consequences were on every page and nobody had named
 * them:
 *
 *   "Skip to content" as a bare blue underlined link at the top left of
 *   every single page, which is what made Mike ask what that alert bar was;
 *   the footer newsletter's "First name" and "Email" labels printed beside
 *   the inputs that already have placeholders saying the same thing.
 *
 * The clip rectangle rather than display:none is deliberate and standard: a
 * screen reader must still reach it, and display:none removes it from the
 * accessibility tree entirely, which would take the skip link away from the
 * people it exists for.
 */
.screen-reader-text {
  position: absolute !important;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  border: 0;
  overflow: hidden;
  clip: rect(1px, 1px, 1px, 1px);
  clip-path: inset(50%);
  white-space: nowrap;
  word-wrap: normal;
}

.screen-reader-text:focus,
.screen-reader-text:focus-visible {
  position: fixed !important;
  top: var(--opl-s5);
  left: var(--opl-s5);
  z-index: 100000;
  width: auto !important;
  height: auto !important;
  clip: auto !important;
  clip-path: none !important;
  overflow: visible !important;
  padding: 12px var(--opl-s6);
  background: var(--opl-ember);
  color: var(--opl-ember-ink);
  font-family: var(--opl-font-head);
  font-weight: 700;
  font-size: var(--opl-size-label);
  letter-spacing: 0.6px;
  text-transform: uppercase;
  text-decoration: none;
  outline: 3px solid var(--opl-white);
  outline-offset: 2px;
}

/*
 * A visible focus ring on everything interactive. The theme had focus rules
 * on a few components and nothing global, so most links fell back to the
 * browser default, which on a dark band is almost invisible.
 */
a:focus-visible,
button:focus-visible,
[tabindex]:not([tabindex="-1"]):focus-visible {
  outline: 3px solid var(--opl-ember);
  outline-offset: 2px;
  border-radius: 2px;
}

/* On the ember button itself an ember ring is invisible, so invert it. */
.opl-btn--ember:focus-visible,
.opl-btn--primary:focus-visible {
  outline-color: var(--opl-white);
}

/* Respect a reduced-motion preference for the one scripted thing we have. */
@media (prefers-reduced-motion: reduce) {
  * { scroll-behavior: auto !important; }
}
