/* typing-test.css — the WPM test page.
   Page-specific only: the shell (nav, ad slots, page-layout, footer) comes from
   critical.css + common.css, and .float-in lives in critical.css. */

/* ══════════════════════════
   HERO — page heading, same construction as the lessons page so the two
   read as one family.
══════════════════════════ */
.test-hero {
  padding: 48px 0 32px;
  text-align: center;
}

.test__h1 {
  font-size: clamp(28px, 3.8vw, 52px);
  font-weight: 700;
  line-height: 1.12;
  letter-spacing: -0.5px;
  color: #eef6ff;
}

.test__h1 .c-yellow {
  color: var(--yellow);
}

/* CMS region — the paragraph arrives from TinyMCE with no class, so every
   text property sits on the WRAPPER and inherits down. Rules that must target
   the element (spacing between paragraphs, links) use descendant selectors.

   The BLOCK is centred under the heading; the TEXT inside runs left. Centred
   text has two ragged edges, so uneven line lengths show on both sides at once
   and read as untidy. Left-aligning gives one straight edge to sit against.
   Justify was tried first and dropped: it flushes both edges but stretches the
   word spaces to do it, which looked worse. */
.test__intro {
  max-width: 68ch;
  margin: 14px auto 0;
  text-align: left;
  font-size: clamp(15px, 1.5vw, 18px);
  font-weight: 600;
  line-height: 1.9;
  color: var(--text-dim);
  opacity: 0;
  animation: testHeadIn 0.9s cubic-bezier(0.22, 1, 0.36, 1) 0.75s forwards;
}
.test__intro p { text-wrap: pretty; }      /* no lone word on the last line */
.test__intro p + p { margin-top: 12px; }
.test__intro a {
  color: var(--yellow);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.test__intro a:hover { color: #ffffff; }

/* H1 fades up on load. */
.test__h1--anim {
  opacity: 0;
  transform: translateY(20px);
  animation: testHeadIn 0.9s cubic-bezier(0.22, 1, 0.36, 1) 0.1s forwards;
}

/* The accent word floats in just after the heading settles — .float-in in
   critical.css does the work; only its delay is overridden here. */
.test__h1--anim .float-in {
  animation-delay: 0.55s;
}

/* ══════════════════════════
   TEST LENGTH — segmented control, same construction as the lessons page's
   level tabs so the two pages read as one family. These are links: each
   length is its own page and its own search term, and a <button> would be
   neither crawlable nor openable in a new tab.
══════════════════════════ */
/* The track uses the same card surface as .cert-teaser below — --card-bg,
   --card-bdr, matching width — so the two stack as one family. It replaces a
   near-black #0f1826 fill that read as a hole in the page rather than a panel
   sitting on it. */
.test-tabs {
  display: flex;
  gap: 0;
  /* min() rather than a flat 720px — the lessons version overflows below that
     viewport width. */
  width: min(720px, 100%);
  margin: 40px auto 0;
  padding: 6px;
  background: var(--card-bg);
  border: 1px solid var(--card-bdr);
  border-radius: 20px;
  opacity: 0;
  animation: testHeadIn 0.7s cubic-bezier(0.22, 1, 0.36, 1) 0.85s forwards;
}

.test-tab {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 18px 0;
  background: transparent;
  /* #C3D0E4 — the label and the icon both take this: the SVGs are drawn with
     stroke/fill="currentColor", so one colour drives the pair. */
  color: var(--text-strong);
  text-decoration: none;
  font-size: 18px;
  font-weight: 700;
  letter-spacing: 0.2px;
  transition: color 0.2s ease, background 0.2s ease;
}

.test-tab__icon {
  display: block;
  width: 32px;
  height: 32px;
  flex-shrink: 0;
  transition: transform 0.3s ease-out;
}

/* Rounded ends only, so the three read as one track. */
.test-tab:first-child { border-radius: 16px 0 0 16px; }
.test-tab:last-child  { border-radius: 0 16px 16px 0; }

/* Dividers on the middle tab give two separators for three tabs, so each
   length reads as its own choice rather than one continuous strip. Same colour
   as the track's own border. box-sizing is border-box globally, so the 2px
   comes out of the tab's width and the three stay equal. */
.test-tab:nth-child(2) {
  border-left: 1px solid var(--card-bdr);
  border-right: 1px solid var(--card-bdr);
}

/* No selected state: all three lead onward to the grade page, which does not
   show this control, so no length is ever "the current one". That makes hover
   the only fill, and the three read as three equal choices. */
.test-tab:hover {
  background: #d6eaf8;
  color: #1A2238;
}
.test-tab:hover .test-tab__icon { transform: translateY(-2px); }

/* Keyboard focus — the ring is a shadow, matching the buttons elsewhere. */
.test-tab:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px var(--yellow);
}

/* ══════════════════════════
   CERTIFICATE TEASER — the reward, promised in a strip rather than rendered
   full size. Kept small on purpose: the test is what the visitor came for, and
   a large certificate above it pushes the action below the fold.
══════════════════════════ */
.cert-teaser {
  display: flex;
  align-items: center;
  gap: 20px;
  width: min(720px, 100%);           /* same track width as the tabs */
  margin: 22px auto 0;
  padding: 14px 20px 14px 14px;
  background: var(--card-bg);
  border: 1px solid var(--card-bdr);
  border-radius: var(--r-lg, 18px);
  opacity: 0;
  animation: testHeadIn 0.7s cubic-bezier(0.22, 1, 0.36, 1) 1s forwards;
}

/* Thumbnail, about a third of the track. At the 132px it started at it read as
   an icon rather than a certificate — too small to show what's being promised.
   No aspect-ratio is forced: the artwork carries its own. */
.cert-teaser__preview {
  flex-shrink: 0;
  display: block;
  width: 230px;
  padding: 0;
  border: 1px solid var(--card-bdr);
  border-radius: 10px;
  background: none;
  overflow: hidden;                  /* clip the artwork to the rounded corners */
  line-height: 0;                    /* no inline-image gap under the picture */
  cursor: pointer;
  transition: border-color 0.2s ease, transform 0.2s ease;
}
.cert-teaser__preview img {
  display: block;
  width: 100%;
  height: auto;
}
.cert-teaser__preview:hover {
  border-color: rgba(255, 255, 255, 0.28);
  transform: translateY(-2px);
}
.cert-teaser__preview:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px var(--yellow);
}

.cert-teaser__text { min-width: 0; text-align: left; }

.cert-teaser__title {
  font-size: clamp(15px, 1.5vw, 17px);
  font-weight: 800;
  color: var(--text-strong);
}

.cert-teaser__sub {
  margin-top: 4px;
  font-size: clamp(13px, 1.3vw, 14px);
  font-weight: 600;
  line-height: 1.6;
  color: var(--text-dim);
}

@media (max-width: 640px) {
  .cert-teaser {
    flex-direction: column;
    gap: 14px;
    padding: 16px;
    text-align: center;
  }
  .cert-teaser__text { text-align: center; }
  .cert-teaser__preview { width: 100%; max-width: 260px; }
}

/* ══════════════════════════
   SEO BLOCK — full-width band below .page-layout, spanning the content column
   and the ad column. The band itself is only a backdrop; the card inside is
   what reads as the section, so there is no top border — the card edge already
   draws that line, and having both stated it twice.

   Every other element on this page is a card (the tab track, the teaser, the
   FAQ items), so a bare block was the odd one out — and at 960px, left-aligned
   text with no container has no right edge to sit against.

   The block had to leave col-content because the benchmark table is unreadable
   at that 680px measure.
══════════════════════════ */
.test-info {
  padding: clamp(36px, 5vw, 60px) 16px clamp(44px, 6vw, 72px);
  background: linear-gradient(to bottom, var(--bg-bot), var(--bg-top));
}

/* One fixed 960px column at every width — prose, list and table share the same
   left and right edge. An earlier version capped the prose narrower and let the
   table break out, which is the usual editorial pattern, but at this content
   length it just read as a ragged block. */
.test-info__inner {
  max-width: 960px;
  margin: 0 auto;
  padding: 40px;
  background: #262B42;
  border-radius: var(--r-lg, 18px);
  font-size: clamp(16px, 1.6vw, 17px);
  font-weight: 600;
  line-height: 1.8;
  /* NOT --text-dim. That token is white-at-58%, and this card lifts the
     background, so it lands at 5.75:1 here against 6.19:1 on a plain band.
     0.62 restores it to 6.32:1 — same fix, same reason, as .faq__a. */
  color: rgba(255, 255, 255, 0.62);
}

/* Everything below targets ELEMENTS, not classes — the content is authored in
   TinyMCE and stored in the database, so it arrives as bare h2/p/ul/table and
   any rule hung on a class would simply never match. */

/* h1 is styled defensively in case an editor picks it, but the PAGE h1 is
   "Typing Test" — a second one here is wrong for search and for screen
   readers. Editors should start at Heading 2. */
.test-info__inner h1,
.test-info__inner h2 {
  position: relative;
  padding-bottom: 15px;              /* room for the accent rule */
  font-size: clamp(22px, 2.4vw, 28px);
  font-weight: 800;
  line-height: 1.3;
  color: var(--text-strong);
}

/* Short accent rule under each major heading. A pseudo-element because the
   heading arrives from TinyMCE and cannot carry extra markup. h3 deliberately
   has none — the rule is what separates the two levels. */
.test-info__inner h1::after,
.test-info__inner h2::after {
  content: '';
  position: absolute;
  left: 0;
  bottom: 0;
  width: 46px;
  height: 3px;
  border-radius: 2px;
  background: var(--yellow);
}

.test-info__inner h3 {
  font-size: clamp(18px, 1.8vw, 21px);
  font-weight: 800;
  line-height: 1.35;
  color: var(--text-strong);
}

/* Spacing is expressed as sibling relationships rather than fixed margins,
   because an editor can reorder blocks freely and nothing should collapse or
   double up. Headings get a large lead-in from whatever precedes them. */
.test-info__inner > * + * { margin-top: 14px; }
.test-info__inner > * + h2 { margin-top: 40px; }
.test-info__inner > * + h3 { margin-top: 34px; }
.test-info__inner > h1 + *,
.test-info__inner > h2 + *,
.test-info__inner > h3 + * { margin-top: 12px; }

/* The global reset in critical.css sets `ul{list-style:none}`, so an unordered
   list from the CMS arrives with NO marker at all — `li::marker` cannot bring
   it back once the list-style is gone. A dash drawn with ::before restores it
   and echoes the heading rule. `ol` is untouched by that reset, so it keeps its
   numbers: an editor who reaches for a numbered list wants the numbers. */
.test-info__inner ul { padding-left: 0; }
.test-info__inner ul > li {
  position: relative;
  padding-left: 22px;
}
.test-info__inner ul > li::before {
  content: '–';
  position: absolute;
  left: 2px;
  top: 0;
  font-weight: 800;
  color: var(--yellow);
}
.test-info__inner ol { padding-left: 22px; }
.test-info__inner ol > li::marker { color: var(--yellow); font-weight: 800; }
.test-info__inner li + li { margin-top: 8px; }

.test-info__inner strong { font-weight: 800; color: var(--text-strong); }
.test-info__inner em { font-style: italic; }

.test-info__inner a {
  color: var(--yellow);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.test-info__inner a:hover { color: #ffffff; }

/* ── Benchmark table ──────────────────────────────────────────────────────
   `separate` rather than `collapse` because border-radius is ignored on a
   collapsed table. Cells carry only a bottom border, so the seams still read
   as single lines. */
.test-info__inner table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  border: 1px solid var(--card-bdr);
  border-radius: var(--r-md);
  overflow: hidden;                  /* clips the header fill to the radius */
  font-size: 15px;
  text-align: left;
}

/* TinyMCE puts the caption above the table; it doubles as the table's
   accessible name, so it stays in the flow rather than being hidden. */
.test-info__inner caption {
  caption-side: top;
  padding-bottom: 10px;
  font-size: 14px;
  font-weight: 600;
  color: var(--text-dim);
  text-align: left;
}

.test-info__inner th,
.test-info__inner td {
  padding: 13px 16px;
  border-bottom: 1px solid var(--card-bdr);
  vertical-align: top;
  text-align: left;
}
.test-info__inner tr:last-child th,
.test-info__inner tr:last-child td { border-bottom: 0; }

.test-info__inner thead th {
  background: rgba(255, 255, 255, 0.05);
  font-size: 12.5px;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-strong);
  white-space: nowrap;
}

/* The row label is the first cell whether the editor emits <th scope="row">
   or a plain <td>, so both are styled — TinyMCE does not always add the th. */
.test-info__inner tbody th,
.test-info__inner tbody td:first-child {
  font-weight: 800;
  color: var(--text-strong);
}
.test-info__inner tbody tr:nth-child(even) { background: rgba(255, 255, 255, 0.02); }

@media (max-width: 760px) {
  /* 40px of card padding inside 16px of band padding leaves under 290px of
     content on a 360px phone. */
  .test-info__inner { padding: 24px 18px; }

  /* Three columns fit a phone, so the cells wrap normally instead of being
     held on one line and scrolled sideways — that was only needed while a
     fourth column of sentence-length text was in play.
     The scroll container stays as a safety net: `display: block` wraps the
     rows in an anonymous table box, so if an editor ever adds a long column
     back, alignment between thead and tbody survives while it scrolls. */
  .test-info__inner table {
    display: block;
    overflow-x: auto;
    font-size: 14px;
  }
  .test-info__inner th,
  .test-info__inner td { padding: 11px 13px; }
}

/* ══════════════════════════
   FAQ — full-width band below the SEO block. Native <details>/<summary>, so
   the toggle, keyboard support and screen-reader semantics come from the
   browser and no JS is loaded for this.
══════════════════════════ */
.faq {
  padding: clamp(36px, 5vw, 60px) 16px clamp(48px, 6vw, 76px);
  background: linear-gradient(to bottom, var(--bg-top), var(--bg-bot));
}

/* Same 960px column as .test-info, so the two bands share one edge. */
.faq__inner { max-width: 960px; margin: 0 auto; }

/* Same heading treatment as the SEO block above, so the two bands read as one
   section rather than two unrelated slabs. */
.faq__title {
  position: relative;
  margin-bottom: 26px;
  padding-bottom: 15px;
  font-size: clamp(22px, 2.4vw, 28px);
  font-weight: 800;
  line-height: 1.3;
  color: var(--text-strong);
}
.faq__title::after {
  content: '';
  position: absolute;
  left: 0;
  bottom: 0;
  width: 46px;
  height: 3px;
  border-radius: 2px;
  background: var(--yellow);
}

/* One column at every width. Two columns were tried and dropped: opening an
   answer on one side left a tall hole on the other, because the grid rows stay
   aligned while only one cell grows. Stacked, the list also reads in a single
   top-to-bottom path — and with only one answer open at a time (see the
   `name="faq"` grouping on the details elements) nothing is ever far off
   screen. */
.faq__list { display: grid; gap: 20px; }

.faq__item {
  background: var(--card-bg);
  border: 1px solid var(--card-bdr);
  border-radius: var(--r-md);
  transition: border-color 0.2s ease;
}
.faq__item:hover,
.faq__item[open] { border-color: rgba(255, 255, 255, 0.18); }

.faq__q {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  padding: 26px 28px;
  cursor: pointer;
  /* A step above the answer's 17px. At the same size the two read as one flat
     block — weight and colour alone are not enough separation once the answer
     runs to several lines. */
  font-size: 18px;
  font-weight: 800;
  line-height: 1.5;
  color: var(--text-strong);
  list-style: none;                  /* Firefox's default triangle */
}
.faq__q::-webkit-details-marker { display: none; }   /* Safari's */

/* The question is an <h3> so it lands in the document outline and is reachable
   by screen-reader heading navigation — <summary> explicitly allows heading
   content. It inherits the summary's type so it stays a flex item, not a
   block that pushes the chevron down. */
.faq__q h3 { font: inherit; color: inherit; }

.faq__q:focus-visible {
  outline: 2px solid var(--yellow);
  outline-offset: -2px;
  border-radius: var(--r-md);
}

/* Chevron drawn in CSS rather than markup — the question is a plain-text CMS
   field, so nothing can be nested inside the summary. */
.faq__q::after {
  content: '';
  flex: none;
  width: 8px;
  height: 8px;
  margin-top: 6px;
  border-right: 2px solid var(--text-dim);
  border-bottom: 2px solid var(--text-dim);
  transform: rotate(45deg);
  transform-origin: 60% 60%;
  transition: transform 0.25s ease, border-color 0.2s ease;
}
.faq__item[open] .faq__q::after { transform: rotate(-135deg); }
.faq__item:hover .faq__q::after {
  border-right-color: var(--text-strong);
  border-bottom-color: var(--text-strong);
}

/* CMS region — the answer body is authored in TinyMCE, so every rule here
   targets elements through the wrapper. */
.faq__a {
  padding: 0 28px 27px;
  font-size: clamp(16px, 1.6vw, 17px);
  font-weight: 600;
  line-height: 1.8;
  /* NOT --text-dim. That token is white-at-58%, and these cards sit on
     --card-bg, which lifts the background by 5% white — so the same token
     lands at 5.68:1 here against 6.19:1 in the SEO block on the plain band.
     0.62 restores it to 6.24:1, matching the body copy above. */
  color: rgba(255, 255, 255, 0.62);
  animation: faqAnswerIn 0.28s cubic-bezier(0.22, 1, 0.36, 1);
}
.faq__a > * + * { margin-top: 12px; }
/* Stops the last line dropping to a single word — the answers are short enough
   that a widow is a large share of what you see. Same treatment as .test__intro. */
.faq__a p { text-wrap: pretty; }

/* Same dash marker as the SEO block — and the same reason: the global
   `ul{list-style:none}` reset leaves an unordered list with no marker. */
.faq__a ul { padding-left: 0; }
.faq__a ul > li { position: relative; padding-left: 20px; }
.faq__a ul > li::before {
  content: '–';
  position: absolute;
  left: 2px;
  top: 0;
  font-weight: 800;
  color: var(--yellow);
}
.faq__a ol { padding-left: 20px; }
.faq__a ol > li::marker { color: var(--yellow); font-weight: 800; }
.faq__a li + li { margin-top: 6px; }
.faq__a strong { font-weight: 800; color: var(--text-strong); }
.faq__a em { font-style: italic; }
.faq__a a {
  color: var(--yellow);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.faq__a a:hover { color: #ffffff; }

/* <details> has no open transition, so the answer fades in rather than the
   panel sliding — a height animation would need ::details-content, which is
   too new to rely on. */
@keyframes faqAnswerIn {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  .faq__a { animation: none; }
  .faq__q::after { transition: none; }
}

/* ── Full-size view ──────────────────────────────────────────────────────
   Native <dialog>: showModal() supplies focus trapping, Escape-to-close and an
   inert background, so none of that is hand-written here. */
/* The dialog fills the screen and centres its card, exactly like the result
   overlay — `dialog:modal` does centre by default, but the UA rules differ
   between engines, so it's stated here rather than relied on. */
.cert-modal {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  max-width: none;                   /* the UA caps both at ~100% - 6px - 2em */
  max-height: none;
  margin: 0;
  padding: 24px;
  border: none;
  background: transparent;           /* ::backdrop supplies the fill */
  display: grid;
  place-items: center;
  overflow: visible;
}
/* Setting display above overrides the UA's `dialog:not([open]) { display:none }`,
   which would leave the dialog painted over the page permanently. */
.cert-modal:not([open]) { display: none; }

/* Same card as the caps warning: --card-bg on the opaque backdrop, 28px radius. */
.cert-modal__inner {
  position: relative;                /* anchors the close button */
  /* Hugs the artwork rather than holding a fixed 760px. On a short viewport the
     image's max-height shrinks it, and a fixed card would leave dead space down
     both sides — most visible at 1366x768, where the viewport is only ~640px
     tall. Capped at 760px so it still matches .result-overlay__inner when there
     is room. */
  width: fit-content;
  max-width: min(760px, 100%);
  padding: 0 0 22px;
  border: 1px solid var(--card-bdr);
  border-radius: 28px;
  background: var(--card-bg);
  color: var(--text-dim);
}
.cert-modal::backdrop {
  /* Fully opaque, exactly like the caps warning — the page behind is hidden
     rather than dimmed, so the certificate is the only thing on screen and no
     background text competes with it. */
  background: linear-gradient(160deg, #1D2540, #141A2E);
}

.cert-modal__close {
  position: absolute;
  top: -16px;
  right: -16px;
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border: 1px solid rgba(255, 255, 255, 0.3);
  border-radius: 50%;
  /* Clearly lighter than the backdrop gradient it sits on — at #1D2540 it was
     the same colour as the backdrop's top stop and effectively invisible. */
  background: #33405F;
  color: #EAF1FB;
  cursor: pointer;
  transition: background 0.2s ease, border-color 0.2s ease;
}
.cert-modal__close svg { width: 18px; height: 18px; }
.cert-modal__close:hover {
  background: #42527A;
  border-color: rgba(255, 255, 255, 0.5);
}
.cert-modal__close:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px var(--yellow);
}

/* A mat around the artwork, the way a mounted certificate sits inside a mount.
   Padding only pays for itself with a background behind it — without one it
   would just duplicate the margin. The radius moves to the image, since the
   image no longer reaches the frame's own corners. */
.cert-modal__frame {
  margin: 18px 18px 14px;
  padding: 10px;
  border-radius: 14px;
  background: rgba(255, 255, 255, 0.04);
  line-height: 0;
}
.cert-modal__frame img {
  border-radius: 6px;
  display: block;
  margin: 0 auto;
  /* Capped to the space the chrome actually takes: 48 dialog padding + 32 frame
     margin + 20 frame padding + 23 hint + 22 card padding = 145, plus a small
     buffer. At the 200px it was, the image shrank further than it needed to and
     left gaps beside it. */
  max-width: 100%;
  max-height: calc(100vh - 165px);
  width: auto;
  height: auto;
}

/* Escape needs no JS — a native modal <dialog> closes on it by default. The
   line is here only so people know it's available. */
.cert-modal__hint {
  margin: 0 18px;
  /* Floors at 14px so it stays legible on a phone, tops out at the 16px it was
     asked for — a flat 16px would crowd the card at small widths. */
  font-size: clamp(14px, 1.4vw, 16px);
  font-weight: 600;
  color: var(--text-strong);                    /* the shared headline tone, not --text-faint */
  text-align: center;
}
.cert-modal__hint kbd {
  display: inline-block;
  min-width: 36px;
  padding: 3px 8px;
  border-radius: 6px;
  background: rgba(255, 255, 255, 0.14);
  box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.22);
  font: inherit;
  font-size: clamp(12px, 1.2vw, 14px);
  font-weight: 800;
  color: #EAF1FB;
}

@media (max-width: 640px) {
  /* At 92vw there's only ~14px of margin left, so the corner button would sit
     on the viewport edge — bring it inside. */
  .cert-modal__close {
    top: 10px;
    right: 10px;
  }
  .cert-modal__frame {
    margin: 14px;
    font-size: 11px;
  }
  .cert-modal__frame svg { width: 40px; height: 40px; }
}

@keyframes testHeadIn {
  from { opacity: 0; transform: translateY(20px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* The heading is decoration on a page you come to in order to type — nobody
   should have to sit through it, and it's motion on load. */
@media (prefers-reduced-motion: reduce) {
  .test__h1--anim,
  .test__intro,
  .test-tabs,
  .cert-teaser {
    opacity: 1;
    transform: none;
    animation: none;
  }
  .test-tab__icon { transition: none; }
}

@media (max-width: 640px) {
  .test-hero {
    padding: 28px 0 20px;
  }
  /* At phone width the block already fills the column, so there's no centred
     box to preserve — and short lines make a ragged left edge more obvious
     than the raggedness it was fixing. */
  .test__intro {
    text-align: center;
  }
  /* Three labels won't sit side by side at phone width without shrinking. */
  .test-tab {
    font-size: 13px;
    padding: 14px 2px;
    gap: 5px;
  }
  .test-tab__icon {
    width: 24px;
    height: 24px;
  }
}
