/* =========================================================================
   Open Psychology Interactives — tool kit
   -------------------------------------------------------------------------
   Shared page furniture for interactive tools: prediction panels, feedback
   boxes, verdict boxes, data tables, charts, stage tracks and the small
   layout helpers that every tool page in this collection needs.

   Why this file exists
   --------------------
   components/interactive-shell.css styles the interactive itself — the frame
   around the visualisation. It deliberately knows nothing about the rest of a
   tool page. But every tool page also has a prediction panel, explanatory
   feedback, a debrief and a limitations panel, and repeating those styles in
   each tool's own tool.css would mean maintaining the same 400 lines in a
   dozen places.

   So: interactive-shell.css frames the interactive; this file styles the page
   around it; tool.css holds only what is genuinely specific to one tool.

   Load order:
       <link rel="stylesheet" href="../../../../assets/css/main.css">
       <link rel="stylesheet" href="../../../../components/interactive-shell.css">
       <link rel="stylesheet" href="../../../../components/tool-kit.css">
       <link rel="stylesheet" href="tool.css">

   Every colour here resolves to a token from main.css, so both the light and
   dark palettes work without restatement. Nothing is hard-coded except the
   system colour keywords in the forced-colours block, which is the one place
   custom properties are not honoured.

   Note: modules/personality-individual-differences/tools/12-alpha-trap/ was
   built before this file existed and carries its own copy of these patterns.
   It is left alone deliberately — it works, it is published, and rewriting a
   released tool to save duplication is not a trade worth making.
   ========================================================================= */

/* -------------------------------------------------------------------------
   Layout helpers
   ---------------------------------------------------------------------- */

/* Equal columns. The site default .split is 3fr/2fr, which is right for
   "content plus sidebar"; these are two peers. */
@media (min-width: 56em) {
  .split--wide {
    grid-template-columns: 1fr 1fr;
  }
}

.how-to {
  padding-left: 1.2rem;
  font-size: var(--text-sm);
}

.how-to > li {
  margin-top: var(--space-2);
}

.table-scroll {
  overflow-x: auto;
  /* A visually-hidden <caption> is absolutely positioned; without a positioned
     ancestor here it resolves against the page and adds roughly 30px of
     spurious scrollable width, so a table that fits still shows a scrollbar. */
  position: relative;
}

/* -------------------------------------------------------------------------
   Prediction panels
   -------------------------------------------------------------------------
   Used for every "commit to an answer before the reveal" panel, and for the
   radio groups inside challenges.
   ---------------------------------------------------------------------- */

.prediction {
  display: grid;
  gap: var(--space-5);
  max-width: 52rem;
}

/* A grid item's automatic minimum size is its min-content width, so a wide
   child — a results table inside a feedback box, most often — pushes the
   whole panel past the viewport and takes the page's horizontal scrollbar
   with it. Every direct child of these grids must be allowed to shrink; wide
   content then scrolls inside its own .table-scroll instead. */
.prediction > *,
.challenge > * {
  min-width: 0;
}

.prediction__group {
  margin: 0;
  padding: 0;
  border: 0;
}

.prediction__legend {
  padding: 0;
  margin-bottom: var(--space-2);
  font-weight: 650;
  font-size: var(--text-base);
}

/* .control--choice is defined in interactive-shell.css, scoped inside
   .interactive. These panels sit outside the shell, so the sizing that makes
   the whole row a 44px target is repeated for them here. */
.prediction .control--choice,
.challenge .control--choice,
.evidence .control--choice {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  min-height: 2.75rem;
  font-size: var(--text-sm);
  cursor: pointer;
}

.prediction .control--choice input,
.challenge .control--choice input,
.evidence .control--choice input {
  width: 1.15rem;
  height: 1.15rem;
  flex: none;
  accent-color: var(--colour-accent);
}

.prediction__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
}

.prediction__error {
  margin: 0;
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--colour-status-border);
  border-left: 4px solid var(--colour-status-border);
  border-radius: var(--radius-sm);
  background-color: var(--colour-status-bg);
  color: var(--colour-status-text);
  font-size: var(--text-sm);
}

.prediction__readback {
  margin: 0;
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--colour-border);
  border-radius: var(--radius-sm);
  background-color: var(--colour-surface-raised);
  font-size: var(--text-sm);
}

/* -------------------------------------------------------------------------
   Feedback
   -------------------------------------------------------------------------
   Explanatory response to what the learner actually did. The tone is always
   also stated in words ("Yes.", "Not quite.") so it never depends on the
   border colour.
   ---------------------------------------------------------------------- */

.feedback {
  padding: var(--space-4);
  border: 1px solid var(--colour-border-strong);
  border-left: 4px solid var(--colour-border-strong);
  border-radius: var(--radius-sm);
  background-color: var(--colour-surface-raised);
  font-size: var(--text-sm);
}

.feedback > :last-child {
  margin-bottom: 0;
}

.feedback[data-tone="good"] {
  border-left-color: var(--colour-neuropsychology);
}

.feedback[data-tone="caution"] {
  border-left-color: var(--colour-cognitive);
}

.feedback[data-tone="warn"] {
  border-left-color: var(--colour-social-critical-psychology);
}

.feedback__verdict {
  font-weight: 700;
}

/* -------------------------------------------------------------------------
   Verdict boxes
   ---------------------------------------------------------------------- */

.verdict {
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--colour-border);
  border-left: 4px solid var(--colour-border-strong);
  border-radius: var(--radius-sm);
  background-color: var(--colour-surface);
}

.verdict__title {
  margin: 0 0 var(--space-2);
  font-size: var(--text-sm);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--colour-text-muted);
}

.verdict__body {
  margin: 0;
  font-size: var(--text-sm);
}

.verdict__body + .verdict__body {
  margin-top: var(--space-2);
}

.verdict__note {
  margin: var(--space-2) 0 0;
  font-size: var(--text-xs);
  color: var(--colour-text-muted);
}

.verdict[data-tone="warn"] {
  border-left-color: var(--colour-social-critical-psychology);
}

.verdict[data-tone="caution"] {
  border-left-color: var(--colour-cognitive);
}

.verdict[data-tone="good"] {
  border-left-color: var(--colour-neuropsychology);
}

/* -------------------------------------------------------------------------
   Goal / task banner
   ---------------------------------------------------------------------- */

.goal {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-2) var(--space-3);
  margin: var(--space-4) 0 0;
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--colour-border-strong);
  border-left: 4px solid var(--colour-accent);
  border-radius: var(--radius-sm);
  background-color: var(--colour-surface-raised);
  font-size: var(--text-sm);
}

/* Shrinks and wraps rather than overflowing: some tools use a long label
   ("Before you can return a verdict"), which at 320px cannot share a line
   with anything and must not force the banner wider than the viewport. */
.goal__label {
  flex: 0 1 auto;
  min-width: 0;
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--colour-text-muted);
}

.goal__text {
  flex: 1 1 16rem;
}

.goal strong {
  font-variant-numeric: tabular-nums;
}

/* Live checklist of requirements, used where a tool has a multi-part goal.
   "(met)" / "(not yet)" is written into the text by the tool, so the marker
   is never the only carrier. */
.goal__checks {
  list-style: none;
  padding: 0;
  margin: var(--space-2) 0 0;
  display: grid;
  gap: 0.15rem;
}

.goal__checks > li {
  margin-top: 0;
  padding-left: 1.4rem;
  position: relative;
}

.goal__checks > li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.35em;
  width: 0.6rem;
  height: 0.6rem;
  border: 2px solid var(--colour-border-strong);
  border-radius: 2px;
}

.goal__checks > li[data-met="yes"]::before {
  border-color: var(--colour-accent);
  background-color: var(--colour-accent);
}

/* -------------------------------------------------------------------------
   Stage track
   ---------------------------------------------------------------------- */

.stage-track {
  list-style: none;
  padding: 0;
  margin: 0 0 var(--space-5);
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  font-size: var(--text-sm);
}

.stage-track > li {
  margin-top: 0;
  flex: 1 1 10rem;
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--colour-border);
  border-bottom: 3px solid var(--colour-border);
  border-radius: var(--radius-sm);
  background-color: var(--colour-surface);
  color: var(--colour-text-muted);
}

.stage-track > li > span {
  font-variant-numeric: tabular-nums;
  font-weight: 700;
}

.stage-track > li[data-state="done"] {
  border-bottom-color: var(--colour-border-strong);
  color: var(--colour-text);
}

.stage-track > li[aria-current="step"] {
  border-bottom-color: var(--colour-accent);
  background-color: var(--colour-accent-soft);
  color: var(--colour-text);
  font-weight: 650;
}

.stage__heading {
  margin: 0;
  font-size: var(--text-base);
}

/* -------------------------------------------------------------------------
   Tables
   ---------------------------------------------------------------------- */

.data-table,
.chart__table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--text-sm);
}

/* `color` is stated rather than inherited. On this site the two are the same,
   but an inherited value loses to any rule that matches the cell directly, and
   an activity exported into somebody else's page meets exactly such rules —
   a themed `.content td { color: #111 }` turned these cells dark against the
   dark-mode panel until this said otherwise. */
.data-table th,
.data-table td,
.chart__table th,
.chart__table td {
  padding: 0.4rem 0.6rem;
  border: 1px solid var(--colour-border);
  text-align: left;
  vertical-align: top;
  color: var(--colour-text);
}

.data-table thead th,
.chart__table thead th {
  background-color: var(--colour-surface);
  font-size: var(--text-xs);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--colour-text-muted);
}

.data-table td,
.chart__table td {
  font-variant-numeric: tabular-nums;
}

.chart__table tbody th,
.data-table tbody th {
  font-weight: 550;
}

.data-table__total > th,
.data-table__total > td {
  border-top: 2px solid var(--colour-border-strong);
  font-weight: 650;
}

/* -------------------------------------------------------------------------
   Charts
   -------------------------------------------------------------------------
   Every chart in this collection is hidden from assistive technology and
   paired with a visible table carrying the same numbers, so the SVG may use
   colour freely — but bars still carry their own value as text, which is what
   keeps them readable in greyscale.
   ---------------------------------------------------------------------- */

.chart {
  margin: 0;
  display: grid;
  gap: var(--space-3);
}

.chart__caption {
  font-size: var(--text-sm);
  font-weight: 650;
}

.chart__svg {
  max-width: 100%;
  height: auto;
}

.chart__label,
.chart__count,
.chart__inline,
.chart__axis {
  font-family: var(--font-body);
  fill: var(--colour-text);
  font-size: 13px;
}

.chart__count,
.chart__axis {
  fill: var(--colour-text-muted);
  font-variant-numeric: tabular-nums;
}

.chart__inline {
  fill: var(--colour-on-accent);
  font-size: 12px;
  font-weight: 650;
}

.chart__track {
  fill: var(--colour-surface);
  stroke: var(--colour-border);
  stroke-width: 1;
}

.chart__bar {
  fill: var(--colour-accent);
}

/* Two-series charts. The pair is distinguished by fill AND by the name
   printed inside each bar, so the distinction survives greyscale. */
.chart__bar--one {
  fill: var(--colour-accent);
}

.chart__bar--two {
  fill: var(--colour-personality-individual-differences);
}

.chart__baseline,
.chart__grid {
  stroke: var(--colour-border);
  stroke-width: 1;
}

.chart__line {
  fill: none;
  stroke: var(--colour-accent);
  stroke-width: 2.5;
}

.chart__line--two {
  stroke: var(--colour-personality-individual-differences);
  stroke-dasharray: 6 4;
}

.chart__point {
  fill: var(--colour-accent);
}

/* -------------------------------------------------------------------------
   Reveal blocks
   ---------------------------------------------------------------------- */

.reveal > :last-child {
  margin-bottom: 0;
}

.reveal__lead {
  font-size: var(--text-lg);
  font-weight: 600;
}

.reveal__figures {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  gap: var(--space-3);
  margin: var(--space-4) 0;
  padding: 0;
  list-style: none;
}

.reveal__figures > li {
  margin-top: 0;
  padding: var(--space-3);
  border: 1px solid var(--colour-border);
  border-radius: var(--radius-sm);
  background-color: var(--colour-surface-raised);
}

.reveal__figure-label {
  display: block;
  font-size: var(--text-xs);
  color: var(--colour-text-muted);
}

.reveal__figure-value {
  display: block;
  font-size: var(--text-xl);
  font-weight: 650;
  font-variant-numeric: tabular-nums;
}

/* -------------------------------------------------------------------------
   Challenges and caution panels
   ---------------------------------------------------------------------- */

.challenge {
  display: grid;
  gap: var(--space-4);
  align-content: start;
}

.challenge__locked {
  margin: 0;
  font-size: var(--text-sm);
  color: var(--colour-text-muted);
}

.panel--caution {
  background-color: var(--colour-status-bg);
  border-color: var(--colour-status-border);
}

.panel--caution li + li {
  margin-top: var(--space-3);
}

/* -------------------------------------------------------------------------
   Forced colours
   -------------------------------------------------------------------------
   Author backgrounds are discarded in this mode, so anything whose boundary
   or state was carried by a tint has to be redrawn with a system colour
   keyword. Same reasoning as the block in interactive-shell.css.
   ---------------------------------------------------------------------- */

@media (forced-colors: active) {
  .goal,
  .verdict,
  .feedback,
  .prediction__error,
  .prediction__readback,
  .stage-track > li,
  .reveal__figures > li {
    border: 1px solid CanvasText;
  }

  .stage-track > li[aria-current="step"] {
    border: 2px solid Highlight;
  }

  .chart__bar,
  .chart__bar--one {
    fill: CanvasText;
  }

  .chart__bar--two {
    fill: Highlight;
  }

  .chart__inline {
    fill: Canvas;
  }

  .chart__line {
    stroke: CanvasText;
  }

  .chart__line--two {
    stroke: Highlight;
  }
}

/* -------------------------------------------------------------------------
   Progressive disclosure inside a stage
   -------------------------------------------------------------------------
   For secondary diagnostics that illustrate the primary result rather than
   adding to it. Folded away by default so they do not compete with the
   teaching effect, and one click from being open.
   ---------------------------------------------------------------------- */

.stage__more {
  border: 1px solid var(--colour-border);
  border-radius: var(--radius-sm);
  background-color: var(--colour-surface);
}

.stage__more > summary {
  padding: var(--space-2) var(--space-3);
  font-size: var(--text-sm);
  font-weight: 600;
  cursor: pointer;
  min-height: 2.75rem;
  display: flex;
  align-items: center;
}

.stage__more[open] > summary {
  border-bottom: 1px solid var(--colour-border);
}

.stage__more > *:not(summary) {
  margin: var(--space-3);
}

/* -------------------------------------------------------------------------
   Activity utilities
   -------------------------------------------------------------------------
   A quiet row beneath an activity holding the two controls that are about
   using the activity rather than about the psychology: Full screen, and Copy
   activity HTML. Deliberately understated, because neither is part of the
   learner's path through the page.

   The two have different fates in an export. Copy activity HTML is a control
   of this website and its block carries data-activity-export, which is how
   scripts/build-standalone.py finds and removes it - a copy must not arrive
   carrying a button that looks for a file no longer beside it. Full screen is
   a usability control and travels with the copy.
   ---------------------------------------------------------------------- */

.activity-utilities {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-3) var(--space-4);
  margin-top: var(--space-4);
  padding: var(--space-3) var(--space-4);
  border: 1px dashed var(--colour-border);
  border-radius: var(--radius-sm);
}

.activity-utilities button {
  min-height: 2.75rem;
  padding: 0.4rem 1rem;
  font: inherit;
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--colour-text);
  background-color: var(--colour-surface);
  border: 1px solid var(--colour-border-strong, var(--colour-border));
  border-radius: var(--radius-sm);
  cursor: pointer;
}

.activity-utilities button:hover {
  background-color: var(--colour-page);
}

/* Never disabled mid-copy: disabling a focused control drops focus to <body>
   and a disabled button cannot be given it back. Copy carries aria-busy
   instead, and is truly disabled only where fetch is unavailable and the copy
   can never work. */
.activity-utilities button[aria-busy="true"] {
  cursor: progress;
}

.activity-utilities button:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

/* Confirmation state. The tick in the label carries the meaning; the colour
   only reinforces it, so nothing is lost when colour is unavailable. */
.activity-utilities button[data-copy-state="ok"] {
  border-color: var(--colour-neuropsychology);
  box-shadow: inset 0 0 0 1px var(--colour-neuropsychology);
}

/* Pressed state for Full screen. aria-pressed carries this for assistive
   technology and the label itself changes to "Exit full screen", so the inset
   line is an echo rather than the only signal. */
.activity-utilities button[aria-pressed="true"] {
  border-color: var(--colour-accent);
  box-shadow: inset 0 0 0 1px var(--colour-accent);
}

/* The two controls that belong to this website rather than to the activity.
   Both are removed from an exported copy; Full screen, which sits outside this
   wrapper, is not. */
.activity-utilities__lecturer {
  display: flex;
  flex: 1 1 20rem;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-3) var(--space-4);
}

/* Download is a link rather than a button, because it points at a file and the
   browser fetches it: there is nothing for a script to do. That keeps it
   working where JavaScript does not, and it guarantees the bytes are the
   committed standalone.html rather than anything reassembled at press time.
   The cost is that it has to be told to size and look like the buttons it
   stands next to. */
.activity-utilities__download {
  display: inline-flex;
  align-items: center;
  min-height: 2.75rem;
  padding: 0.4rem 1rem;
  font: inherit;
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--colour-text);
  text-decoration: none;
  background-color: var(--colour-surface);
  border: 1px solid var(--colour-border-strong, var(--colour-border));
  border-radius: var(--radius-sm);
}

/* Presented as a button among buttons, so the underline is dropped at rest and
   brought back on hover and focus rather than given up altogether. */
.activity-utilities__download:hover,
.activity-utilities__download:focus-visible {
  background-color: var(--colour-page);
  text-decoration: underline;
}

.activity-utilities__note {
  flex: 1 1 16rem;
  margin: 0;
  font-size: var(--text-sm);
  color: var(--colour-text-muted);
}

@media (forced-colors: active) {
  .activity-utilities button {
    border: 1px solid ButtonBorder;
  }

  .activity-utilities button[aria-pressed="true"] {
    border: 2px solid Highlight;
  }

  .activity-utilities__download {
    color: LinkText;
    border: 1px solid LinkText;
  }
}

/* -------------------------------------------------------------------------
   Full-screen state
   -------------------------------------------------------------------------
   The element put full screen is the exported `.opi-activity` wrapper where
   there is one, and this site's <main> otherwise - never <body>, which would
   take the header and footer with it.

   A full-screen element is sized to the screen and clips what overflows, so
   an activity taller than the display needs `overflow-y: auto` or its debrief
   becomes unreachable. It also needs a background of its own: the default
   backdrop is black, and these panels assume the page colour behind them.
   ---------------------------------------------------------------------- */

.opi-activity:fullscreen,
main:fullscreen,
.interactive:fullscreen {
  overflow-y: auto;
  overscroll-behavior: contain;
  background-color: var(--colour-page);
  color: var(--colour-text);
}

main:fullscreen > .section:first-child,
.opi-activity:fullscreen > .section:first-child {
  padding-top: var(--space-5);
}

/* -------------------------------------------------------------------------
   Optional learner support
   -------------------------------------------------------------------------
   The "Need a hand?" and "Key terms" disclosures. Both are deliberately
   subordinate to the activity: smaller type, no fill, a plain summary rather
   than a button. Collapsed, either one is a single line, and a learner who
   does not need it reads past it.

   Two shapes use these rules:

     .helper[data-learner-help]  a guide plus a nested "Key terms" list. The
                                 attribute is what components/learner-help.js
                                 binds to.
     .helper                     "Key terms" alone, with no script at all.

   Sixteen activities have the guide; the rest that have support carry the
   glossary only, because a guide there would restate what the page already
   says. See docs/adapting-a-tool.md.
   ---------------------------------------------------------------------- */

.helper {
  margin-bottom: var(--space-4);
  font-size: var(--text-sm);
}

.helper__summary {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: 2.75rem;
  padding: 0 var(--space-2);
  font-weight: 600;
  color: var(--colour-text-muted);
  cursor: pointer;
  border-radius: var(--radius-sm);
}

.helper__summary:hover {
  color: var(--colour-text);
}

.helper[open] > .helper__summary {
  color: var(--colour-text);
}

.helper__body {
  margin: var(--space-2) 0 0;
  padding: var(--space-3) var(--space-4);
  border-left: 3px solid var(--colour-border-strong);
  background-color: var(--colour-surface);
  border-radius: var(--radius-sm);
}

.helper__offer {
  margin: 0;
}

.helper__start,
.helper__actions button {
  min-height: 2.75rem;
  padding: 0.4rem 1rem;
  font: inherit;
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--colour-on-accent);
  background-color: var(--colour-accent);
  border: 1px solid var(--colour-accent);
  border-radius: var(--radius-sm);
  cursor: pointer;
}

.helper__actions button[data-variant="secondary"] {
  color: var(--colour-text);
  background-color: transparent;
  border-color: var(--colour-border-strong);
}

.helper__actions button:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.helper__progress {
  margin: 0 0 var(--space-2);
  font-size: var(--text-xs);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--colour-text-muted);
}

/* The step is the one thing in here that should read as prose.

   min-height reserves two lines. Without it a step that wraps to a second line
   makes the panel taller and pushes the activity down by a line, so the thing
   the learner has just been told to look at moves as they press Next. Every
   step in the collection is written to fit two lines at a normal reading
   width, which is what makes one shared reservation workable. */
.helper__step {
  margin: 0 0 var(--space-3);
  max-width: 42rem;
  min-height: 3.4em;
}

/* On a phone the same sentences wrap to as many as four lines, so two is not
   enough to hold the panel still. Reserving four costs some blank space under
   the shorter steps and buys an activity that does not move under the reader. */
@media (max-width: 40em) {
  .helper__step {
    min-height: 6.8em;
  }
}

.helper__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.helper__aside {
  margin: var(--space-3) 0 0;
  font-size: var(--text-xs);
  color: var(--colour-text-muted);
}

/* The nested glossary inside a guide. Where the glossary is the whole body,
   it needs no divider above it. */
.helper__terms {
  margin-top: var(--space-4);
  padding-top: var(--space-3);
  border-top: 1px solid var(--colour-border);
}

.helper__glossary {
  margin: var(--space-2) 0 0;
  display: grid;
  gap: var(--space-2);
}

.helper__body > .helper__glossary {
  margin-top: 0;
}

.helper__glossary dt {
  font-weight: 650;
}

.helper__glossary dd {
  margin: 0 0 var(--space-2);
  max-width: 42rem;
  color: var(--colour-text-muted);
}

.helper__glossary dd:last-child {
  margin-bottom: 0;
}

/* The step's target. An outline is painted outside the box, so nothing on the
   page moves when it appears or goes - which matters because these sit beside
   charts that are expensive to reflow. Decoration only: every step names its
   target in words, so nothing depends on seeing this. */
[data-guide-target] {
  outline: 3px solid var(--colour-focus);
  outline-offset: 3px;
  border-radius: var(--radius-sm);
}

@media (forced-colors: active) {
  [data-guide-target] {
    outline: 3px solid Highlight;
  }

  .helper__body {
    border-left: 3px solid CanvasText;
  }
}
