/* ==========================================================================
   PasswordRadar landing page: home.css
   Page-only styles for index.html, on top of site.css (tokens, type, layout
   and every shared component). Tokens only, no raw colours; page classes
   carry the home- prefix.

    1  Page type              8  Who runs PasswordRadar
    2  Hero                   9  Pricing
    3  Radar scope           10  Roadmap
    4  Demo                  11  FAQ
    5  Integration (#api)    12  Final call to action
    6  Coverage              13  Dialogs
    7  NIS2 and your auditor
   ========================================================================== */


/* 1  Page type ============================================================= */

/* the landing lede steps down on phones, so the hero scope reaches the first screen (UI-07) */
.lede {
  font-size: clamp(1.125rem, 1rem + 0.8vw, 1.3125rem);
}

/* a heading with its status tag beside it: the tag stays out of the heading's name (UX-22) */
.home-name {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.375rem 0.625rem;
}

/* the legend marks of the scope: dot = leaked or common, ring = tailored guess */
.home-mark {
  display: inline-block;
  flex: none;
  width: 0.625rem;
  height: 0.625rem;
  margin-right: 0.375em;
  border-radius: 50%;
  vertical-align: -0.02em;
}

.home-mark--dot {
  background-color: var(--signal-ink);
}

.home-mark--ring {
  border: 2px solid var(--signal-ink);
}

/* UI-18: every call-to-action cluster stacks full width on narrow phones */
@media not all and (min-width: 30em) {
  .home-api__actions > .btn,
  .home-file__actions > .btn,
  .home-cta__actions > .btn { flex: 1 1 100%; }
}


/* 2  Hero ================================================================== */

.home-hero {
  padding-block: clamp(2.5rem, 1rem + 4.5vw, 4.5rem) var(--section-pad);
}

.home-hero__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  row-gap: var(--space-7);
}

.home-hero__title {
  max-width: 9.5em;
}

.home-hero__lede {
  margin-top: var(--space-5);
  max-width: 28em;
}

/* each action carries one honest line: what it gets you, and its status */
.home-hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4) var(--space-3);
  margin-top: var(--space-6);
}

.home-hero__action {
  display: grid;
  gap: var(--space-2);
  justify-items: start;
}

/* one plain sentence: who runs it, where, and the way to the NIS2 evidence (UI-31, UX-14) */
.home-hero__facts {
  max-width: 34em;
  color: var(--ink-2);
}

/* UX-30: a 44px touch height for the two inline links, without changing the line box */
@media (pointer: coarse) {
  .home-hero__facts a { padding-block: 0.75em; }
}

@media not all and (min-width: 30em) {
  .home-hero__action { flex: 1 1 100%; justify-items: stretch; }
}

@media not all and (min-width: 64em) {
  .home-hero__facts { margin-top: calc(var(--space-6) - var(--space-7)); }
}

/* desktop: copy and facts on the left, the scope on the right, all top-aligned (UX-03) */
@media (min-width: 64em) {
  .home-hero__grid {
    grid-template-columns: repeat(12, minmax(0, 1fr));
    grid-template-rows: auto 1fr;
    column-gap: var(--gutter);
    row-gap: var(--space-6);
    align-items: start;
  }
  .home-hero__copy { grid-column: 1 / span 6; grid-row: 1; }
  .home-scope { grid-column: 7 / -1; grid-row: 1 / span 2; justify-self: end; }
  .home-hero__facts { grid-column: 1 / span 6; grid-row: 2; }
  /* half a container wide: "your people" must fit on one line (about 6.8em wide at 125%) */
  .home-hero__title { font-size: min(var(--display-xl), 6.3vw); }
}

/* short laptop windows (1280x600, 1366x680, 1440x760): the headline, the full lede and both calls
   to action fit in the first screen (UI-01, UX-03) */
@media (min-width: 64em) and (max-height: 56em) {
  .home-hero { padding-top: var(--space-6); }
  .home-hero__title { font-size: min(var(--display-xl), 6.3vw, 9.5vh); }
  .home-hero__lede { margin-top: var(--space-4); font-size: 1.125rem; }
  .home-hero__actions { margin-top: var(--space-5); }
}


/* 3  Radar scope ===========================================================
   The one bold element. A plan position indicator: range rings, bearing
   ticks, an amber phosphor sweep, and blips that light up as the beam passes
   the bucket their password hashes to. Filled dots are leaked or common
   passwords; rings are tailored guesses. The disc is an instrument surface
   (.theme-scope), dark in both themes.

   Motion: one CSS clock. The sweep turns once per --period; every blip and
   tag runs a keyframe loop of the same length, with a negative delay set
   from its bearing, so it fires exactly when the beam crosses it and the
   first frame already looks like a scope that has been running. The beam
   starts at 000 and passes four of the five tailored guesses (007-067) in
   its first 1.7 seconds; the fifth sits at 303. The still frame rests at
   --lead (070), just past those four. Only opacity and transform move.
   .is-running starts the clock, .is-paused holds it (pause button,
   off-screen, hidden tab), .is-static is the reduced-motion scope,
   .is-compact the small-disc tags. */

.home-scope {
  width: 100%;
  max-width: 36rem;
  margin: 0;
}

/* desktop: the whole disc stays in the first screen, next to the headline (UI-01) */
@media (min-width: 64em) {
  .home-scope { max-width: min(36rem, calc(100vh - var(--header-h) - 3rem)); }
}

.home-scope__disc {
  --period: 9s;
  --lead: 70deg;
  position: relative;
  aspect-ratio: 1;
  border-radius: 50%;
  container: scope / inline-size;
  box-shadow:
    0 0 0 1px var(--line-2),
    0 36px 72px -36px color-mix(in srgb, var(--scope) 75%, transparent);
}

/* dark pages: a drop shadow disappears, so a bezel gives the disc its edge (UI-13).
   Inside .theme-scope these tokens are the scope's own, the same in both themes. */
:root[data-theme="dark"] .home-scope__disc {
  box-shadow: 0 0 0 1px var(--line-2), 0 0 0 10px var(--surface), 0 0 0 11px var(--line);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .home-scope__disc {
    box-shadow: 0 0 0 1px var(--line-2), 0 0 0 10px var(--surface), 0 0 0 11px var(--line);
  }
}

.home-scope__grid {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
}

.home-scope__ring,
.home-scope__cross,
.home-scope__tick {
  fill: none;
  stroke: var(--scope-grid);
  stroke-width: 1;
  vector-effect: non-scaling-stroke;
}

.home-scope__ring--outer {
  stroke: var(--line-2);
  stroke-width: 1.5;
}

.home-scope__cross {
  opacity: 0.7;
}

.home-scope__tick--major {
  stroke: var(--line-2);
  stroke-width: 1.5;
}

/* bearing labels sit in the middle of the band between the tick ends (r 446) and the rim (r 500),
   about 10 units clear of both (UI-19) */
.home-scope__labels {
  fill: var(--scope-dim);
  font-family: var(--font-mono);
  font-size: 18px;          /* SVG user units: about 10px on a 576px disc */
  text-anchor: middle;
  dominant-baseline: central;
}

.home-scope__hub {
  fill: var(--scope-dim);
}

/* the beam and its phosphor afterglow: a steep ramp just behind the beam that decays over about
   110 degrees (UI-20). The sweep is a round clip; the arm inside it turns (a turning square would
   otherwise poke out of the disc at 45 degrees and widen the page). */
.home-scope__sweep {
  position: absolute;
  inset: 8%;                /* range-ring radius: 420 of 500 */
  overflow: hidden;
  border-radius: 50%;
}

.home-scope__arm {
  position: absolute;
  inset: 0;
  background: conic-gradient(
    from 0deg,
    transparent 0deg 250deg,
    color-mix(in srgb, var(--scope-signal) 3%, transparent) 300deg,
    color-mix(in srgb, var(--scope-signal) 9%, transparent) 335deg,
    color-mix(in srgb, var(--scope-signal) 20%, transparent) 352deg,
    color-mix(in srgb, var(--scope-signal) 42%, transparent) 360deg
  );
  transform: rotate(0deg);
}

.home-scope__beam {
  position: absolute;
  left: calc(50% - 1px);
  top: 0;
  width: 2px;
  height: 50%;
  border-radius: 1px;
  background: linear-gradient(to top, color-mix(in srgb, var(--scope-signal) 20%, transparent), var(--scope-signal));
}

.home-scope.is-running .home-scope__arm {
  animation: home-sweep var(--period) linear var(--arm-delay, 0s) infinite;
  will-change: transform;
}

.home-scope.is-static .home-scope__arm,
:root:not(.has-js) .home-scope__arm,
:root.home-js-failed .home-scope__arm {
  transform: rotate(var(--lead));
}

/* contacts: a zero-size anchor at the blip's bucket, with the blip and its data tag */
.home-scope__contacts {
  position: absolute;
  inset: 0;
}

.home-contact {
  position: absolute;
  width: 0;
  height: 0;
}

/* leaked or common: a filled return */
.home-contact__blip {
  position: absolute;
  left: -4px;
  top: -4px;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background-color: var(--scope-signal);
  opacity: 0;
}

/* tailored guess: a ring, generated for acme.example rather than seen in the wild (UI-02) */
.home-contact--tailored .home-contact__blip {
  left: -5.5px;
  top: -5.5px;
  width: 11px;
  height: 11px;
  border: 2px solid var(--scope-signal);
  background-color: transparent;
}

/* the flash when the beam passes */
.home-contact__blip::after {
  content: "";
  position: absolute;
  inset: -6px;
  border-radius: 50%;
  background-color: color-mix(in srgb, var(--scope-signal) 45%, transparent);
  opacity: 0;
}

/* data tag: password over category, offset from the blip with a leader line. Its size follows the
   disc (2.17cqi is 12.5px on a 576px disc), so one placement table holds on every desktop disc.
   data-side = e | w | n | s; --ny nudges it along the other axis (-1 to 1). */
.home-contact__tag {
  --g: 12px;                /* blip centre to tag edge */
  position: absolute;
  left: 0;
  top: 0;
  display: block;
  padding: 0.3em 0.6em 0.35em;
  border: 1px solid var(--scope-grid);
  border-radius: var(--r-sm);
  background-color: color-mix(in srgb, var(--scope) 90%, transparent);
  font-family: var(--font-mono);
  font-size: 10.5px;                           /* engines without container units */
  font-size: clamp(10.5px, 2.17cqi, 12.5px);
  line-height: 1.3;
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
}

.home-contact__tag b {
  display: block;
  color: var(--scope-signal);
  font-weight: 600;
}

.home-contact__tag span {
  display: block;
  color: var(--scope-dim);
  font-size: 0.85em;
}

/* tailored tags read as the signal they are: amber category, amber-tinted frame */
.home-contact--tailored .home-contact__tag {
  border-color: color-mix(in srgb, var(--scope-signal) 45%, var(--scope-grid));
}

/* Engines without color-mix() (Safari before 16.2, Chrome before 111): a declaration that holds
   var() is accepted when parsed and fails only later, so a plain value written before it never
   applies. These do, in fixed colours (the scope is the same in both themes); the dark themes'
   bezel above is more specific than the disc's shadow here, so it still wins. */
@supports not (color: color-mix(in srgb, red 50%, transparent)) {
  .home-scope__disc { box-shadow: 0 0 0 1px var(--line-2), 0 36px 72px -36px rgba(7, 18, 24, 0.75); }
  .home-scope__arm {
    background: conic-gradient(from 0deg, transparent 0deg 250deg, rgba(255, 178, 36, 0.03) 300deg,
      rgba(255, 178, 36, 0.09) 335deg, rgba(255, 178, 36, 0.2) 352deg, rgba(255, 178, 36, 0.42) 360deg);
  }
  .home-scope__beam { background: linear-gradient(to top, rgba(255, 178, 36, 0.2), var(--scope-signal)); }
  .home-contact__blip::after { background-color: rgba(255, 178, 36, 0.45); }
  .home-contact__tag { background-color: rgba(7, 18, 24, 0.9); }
  .home-contact--tailored .home-contact__tag { border-color: rgb(129, 108, 51); }
}

.home-contact--tailored .home-contact__tag span {
  color: var(--scope-signal);
}

.home-contact__tag::before {
  content: "";
  position: absolute;
  background-color: var(--scope-dim);
}

.home-contact__tag[data-side="e"] { transform: translate(var(--g), calc(-50% + var(--ny, 0) * 40%)); }
.home-contact__tag[data-side="w"] { transform: translate(calc(-100% - var(--g)), calc(-50% + var(--ny, 0) * 40%)); }
.home-contact__tag[data-side="n"] { transform: translate(calc(-50% + var(--ny, 0) * 40%), calc(-100% - var(--g))); }
.home-contact__tag[data-side="s"] { transform: translate(calc(-50% + var(--ny, 0) * 40%), var(--g)); }

.home-contact__tag[data-side="e"]::before,
.home-contact__tag[data-side="w"]::before {
  top: calc(50% - var(--ny, 0) * 40%);
  width: calc(var(--g) - 6px);
  height: 1px;
}

.home-contact__tag[data-side="e"]::before { right: calc(100% + 1px); }
.home-contact__tag[data-side="w"]::before { left: calc(100% + 1px); }

.home-contact__tag[data-side="n"]::before,
.home-contact__tag[data-side="s"]::before {
  left: calc(50% - var(--ny, 0) * 40%);
  width: 1px;
  height: calc(var(--g) - 6px);
}

.home-contact__tag[data-side="n"]::before { top: calc(100% + 1px); }
.home-contact__tag[data-side="s"]::before { bottom: calc(100% + 1px); }

/* the clock: each contact carries --delay = minus (how long ago the beam passed it) */
.home-scope.is-running .home-contact__blip {
  animation: home-blip var(--period) linear var(--delay, 0s) infinite;
}

.home-scope.is-running .home-contact__blip::after {
  animation: home-flash var(--period) ease-out var(--delay, 0s) infinite;
}

.home-scope.is-running .home-contact__tag {
  animation: home-tag var(--period) linear var(--delay, 0s) infinite;
}

.home-scope.is-running.is-compact .home-contact__tag {
  animation-name: home-tag-brief;
}

.home-scope.is-paused .home-scope__arm,
.home-scope.is-paused .home-contact__blip,
.home-scope.is-paused .home-contact__blip::after,
.home-scope.is-paused .home-contact__tag {
  animation-play-state: paused;
}

/* reduced motion: a still scope, every blip shown with its afterglow (--glow),
   a readable subset of tags */
.home-scope.is-static .home-contact__blip {
  opacity: var(--glow, 1);
}

.home-scope.is-static .home-contact__tag.is-shown {
  opacity: 1;
}

@keyframes home-sweep {
  to { transform: rotate(1turn); }
}

/* one sweep: bright as the beam passes, then phosphor decay until the next pass */
@keyframes home-blip {
  0% { opacity: 1; }
  15% { opacity: 0.8; }
  55% { opacity: 0.42; }
  100% { opacity: 0.26; }
}

@keyframes home-flash {
  0% { opacity: 0.9; transform: scale(0.6); }
  14% { opacity: 0; transform: scale(2.2); }
  100% { opacity: 0; transform: scale(2.2); }
}

/* wide discs: a tag stays up for about 80 degrees of sweep */
@keyframes home-tag {
  0% { opacity: 0; }
  1.5% { opacity: 1; }
  19% { opacity: 1; }
  22% { opacity: 0; }
  100% { opacity: 0; }
}

/* compact discs: about 35 degrees, so neighbours never share the screen */
@keyframes home-tag-brief {
  0% { opacity: 0; }
  1.5% { opacity: 1; }
  8% { opacity: 1; }
  10% { opacity: 0; }
  100% { opacity: 0; }
}

@container scope (max-width: 26rem) {
  .home-scope__labels,
  .home-scope__tick--minor { display: none; }
}

@container scope (max-width: 24.99rem) {
  .home-contact__tag { --g: 10px; }
  .home-contact__blip { left: -3.5px; top: -3.5px; width: 7px; height: 7px; }
  .home-contact--tailored .home-contact__blip { left: -5px; top: -5px; width: 10px; height: 10px; }
}

@container scope (max-width: 19rem) {
  .home-contact__tag { font-size: 10px; }
}

/* the disc and its pause knob, which sits in the empty corner of the disc's square */
.home-scope__stage {
  position: relative;
}

/* pause: a visible, remembered toggle for the one moving thing on the site (UX-05, WCAG 2.2.2).
   Pressed means paused. */
.home-scope__pause {
  position: absolute;
  right: 0;
  bottom: 0;
  display: grid;
  place-items: center;
  width: 2.75rem;
  height: 2.75rem;
  padding: 0;
  border: 1px solid var(--field);
  border-radius: 50%;
  background: var(--paper);
  color: var(--ink);
  transition: border-color 0.12s ease, background-color 0.12s ease, color 0.12s ease;
}

.home-scope__pause:hover {
  border-color: var(--ink);
  background: var(--surface);
}

.home-scope__pause[aria-pressed="true"] {
  border-color: var(--ink);
  background: var(--ink);
  color: var(--paper);
}

.home-scope__pause .icon {
  width: 1.125rem;
  height: 1.125rem;
  stroke-width: 2.5;
}

.home-scope__nojs { display: none; }
:root:not(.has-js) .home-scope__nojs,
:root.home-js-failed .home-scope__nojs { display: inline; }
:root:not(.has-js) .home-scope__legend,
:root:not(.has-js) .home-scope__pause,
:root.home-js-failed .home-scope__legend,
:root.home-js-failed .home-scope__pause,
.home-scope.is-static .home-scope__pause {
  display: none;
}

/* the readout: what the beam just passed, and the only thing we would ever see of it, its bucket.
   Fixed widths, so the changing values never reflow the strip (UX-05). */
.home-scope__readout {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3) var(--space-5);
  margin: var(--space-6) 0 0;
  padding-top: var(--space-4);
  border-top: 1px solid var(--line);
}

.home-scope__readout > div {
  min-width: 0;
}

.home-scope__readout dt {
  color: var(--ink-3);
  font-size: var(--text-xs);
  font-weight: 500;
  line-height: 1.4;
}

.home-scope__readout dd {
  margin: 0.125rem 0 0;
  color: var(--ink);
  font-size: var(--text-sm);
  font-weight: 560;
  line-height: 1.45;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.home-scope__readout .mono {
  font-size: 0.8125rem;
  font-weight: 500;
}

.home-scope__pw {
  display: inline-block;
  min-width: 13ch;          /* the longest sample, in Martian Mono's own ch */
}

.home-scope__cat {
  min-width: 8.25em;        /* "Masks & patterns" */
}

.home-scope__caption {
  margin-top: var(--space-3);
  max-width: 36em;
}

/* tablets: the scope sits beside its readout and caption */
@media (min-width: 40em) and (max-width: 63.999em) {
  .home-scope {
    display: grid;
    grid-template-columns: minmax(0, 3fr) minmax(0, 2fr);
    grid-template-rows: auto 1fr;
    column-gap: var(--space-6);
    max-width: none;
  }
  .home-scope__stage { grid-row: 1 / span 2; }
  .home-scope__readout {
    flex-direction: column;
    align-self: end;
    margin-top: 0;
    padding-top: 0;
    border-top: 0;
  }
  .home-scope__caption { align-self: start; margin-top: var(--space-4); }
}


/* 4  Demo ==================================================================
   Phones: intro, result, tip, so the verdict sits right under the samples (UX-07).
   Desktop: intro and tip on the left, the result panel on the right grid line
   that the code block below uses too (UI-09). */

.home-demo {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  row-gap: var(--space-6);
}

@media (min-width: 64em) {
  .home-demo {
    grid-template-columns: repeat(12, minmax(0, 1fr));
    grid-template-rows: auto 1fr;
    column-gap: var(--gutter);
    align-items: start;
  }
  .home-demo__intro { grid-column: 1 / span 5; grid-row: 1; }
  .home-demo__result { grid-column: 6 / -1; grid-row: 1 / span 2; }
  .home-demo__tip { grid-column: 1 / span 5; grid-row: 2; }
}

.home-demo__intro > * + * {
  margin-top: var(--space-5);
}

.home-demo__intro > .lede {
  margin-top: var(--space-4);
}

/* 16px: iOS Safari zooms into anything smaller when it takes focus (UX-07) */
.home-demo .input--mono {
  font-size: 1rem;
}

/* the field and its Check button share a row: typing sends nothing, Check or Enter runs the check */
.home-demo__row {
  display: flex;
  gap: var(--space-2);
}

.home-demo__row > .input {
  flex: 1 1 auto;
  min-width: 0;
}

.home-demo__check {
  flex: none;
}

.home-demo__chips {
  --cluster-gap: var(--space-2);
  margin-top: var(--space-3);
}

.home-demo__chips .chip.is-current {
  border-color: var(--ink);
  box-shadow: inset 0 0 0 1px var(--ink);
}

.home-demo__panel {
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.home-demo__head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0 var(--space-4);
  min-height: 2.75rem;
  padding: 0.25rem 1.25rem;
  border-bottom: 1px solid var(--scope-grid);
  background-color: var(--scope-2);
  color: var(--scope-dim);
  font-size: var(--text-xs);
  line-height: 1.4;
}

.home-demo__mode {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  color: var(--scope-text);
  font-weight: 600;
}

.home-demo__retry {
  min-height: 2.75rem;
  margin-left: auto;
  color: var(--scope-text);
  font-size: var(--text-xs);
}

/* the verdict, readable without parsing the trace (UI-08): a word in the verdict's colour with a
   matching dot, then what it means */
.home-verdict {
  margin: 0;
  padding: 1rem 1.25rem 0.9375rem;
  border-bottom: 1px solid var(--scope-grid);
  color: var(--scope-text);
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: 520;
  font-stretch: 104%;
  line-height: 1.35;
  letter-spacing: -0.005em;
}

.home-verdict__word {
  font-weight: 700;
}

.home-verdict__word::before {
  content: "";
  display: inline-block;
  width: 0.5em;
  height: 0.5em;
  margin-right: 0.4em;
  border-radius: 50%;
  background-color: currentColor;
  vertical-align: 0.08em;
}

.home-verdict--idle,
.home-verdict--pending {
  color: var(--scope-dim);
}

.home-verdict--known .home-verdict__word { color: var(--alert); }
.home-verdict--weak .home-verdict__word { color: var(--signal); }
.home-verdict--clear .home-verdict__word { color: var(--clear); }

.home-demo__out {
  min-height: 15rem;
  padding: 0.875rem 1.25rem 1.375rem;
  color: var(--scope-text);
  font-family: var(--font-mono);
  font-size: 0.8125rem;
  line-height: 1.75;
  overflow-wrap: anywhere;
}

/* the idle example run is monochrome: plainly not a result, and still AA on the scope */
.home-demo__out.is-example {
  color: var(--scope-dim);
}

.home-demo__out.is-example :is(.tc, .tk, .ts, .tf, .tn) {
  color: inherit;
}

.home-demo__nojs {
  display: none;
  padding: 1.25rem;
  color: var(--scope-text);
  font-size: var(--text-sm);
}

/* without JavaScript nothing here can run: say so, and don't pretend to probe or wait. The same
   when home.js never ran (site.js sets .home-js-failed). */
:root:not(.has-js) .home-demo__nojs,
:root.home-js-failed .home-demo__nojs {
  display: block;
}

:root:not(.has-js) .home-demo__head,
:root:not(.has-js) .home-verdict,
:root:not(.has-js) .home-demo__out,
:root:not(.has-js) .home-scope__readout,
:root.home-js-failed .home-demo__head,
:root.home-js-failed .home-verdict,
:root.home-js-failed .home-demo__out,
:root.home-js-failed .home-scope__readout {
  display: none;
}

.home-trace__hash {
  word-break: break-all;
}

.home-trace__final {
  display: inline-block;
  margin-top: 0.375rem;
  color: var(--scope-text);
}


/* 5  Integration (#api) and coding assistants (#agents) ==================== */

.home-api {
  margin-top: var(--space-9);
}

.home-api__steps > * + * {
  margin-top: var(--space-5);
}

.home-api__steps > .steps {
  margin-top: var(--space-6);
}

.home-api__code {
  min-width: 0;
}

.home-api__fail,
.home-api__salt {
  margin-top: var(--space-3);
  max-width: 44em;
}

.home-api__more {
  margin-top: var(--space-8);
}

.home-api__more p {
  max-width: var(--measure);
  margin-top: var(--space-2);
  color: var(--ink-2);
}


/* 6  Coverage ============================================================== */

.home-coverage__head > p:not(.lede) {
  max-width: var(--measure);
  color: var(--ink-2);
}

.home-coverage {
  display: grid;
  gap: var(--space-7) var(--gutter);
  margin-top: var(--space-8);
}

@media (min-width: 48em) {
  .home-coverage { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .home-coverage__group--yours { grid-column: 1 / -1; }
}

@media (min-width: 64em) {
  .home-coverage { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .home-coverage__group--yours { grid-column: auto; }
}

.home-coverage__group {
  padding-top: var(--space-4);
  border-top: 1px solid var(--line-2);
}

.home-coverage__kind {
  margin-top: 0.25rem;
  color: var(--ink-3);
  font-size: var(--text-sm);
}

.home-coverage__list {
  display: grid;
  gap: var(--space-5);
  margin: var(--space-5) 0 0;
  padding: 0;
  list-style: none;
}

.home-coverage__list p {
  max-width: 30em;
  margin-top: var(--space-1);
  color: var(--ink-2);
  font-size: var(--text-sm);
  line-height: 1.55;
}

.home-coverage__data {
  max-width: var(--measure-wide);
  margin-top: var(--space-7);
  color: var(--ink-2);
}


/* 7  NIS2 and your auditor ================================================= */

.home-rules {
  margin-top: var(--space-8);
}

.home-rules__intro > * + * {
  margin-top: var(--space-2);
}

.home-rules__grid {
  display: grid;
  margin-top: var(--space-5);
  border-top: 1px solid var(--line-2);
}

.home-rule {
  padding-block: var(--space-5);
}

.home-rule > * + * {
  margin-top: var(--space-3);
}

.home-rule p,
.home-rule dd {
  color: var(--ink-2);
  font-size: var(--text-sm);
  line-height: 1.55;
}

.home-rule__law {
  margin-block: var(--space-4) 0;
}

.home-rule__law > div + div {
  margin-top: var(--space-3);
}

.home-rule__law dt {
  color: var(--ink);
  font-size: var(--text-sm);
  font-weight: 650;
}

.home-rule__law dd {
  margin: 0.125rem 0 0;
}

@media not all and (min-width: 64em) {
  .home-rule + .home-rule { border-top: 1px solid var(--line); }
}

/* desktop: NIS2, the longest and the one this audience came for, gets the wide column */
@media (min-width: 64em) {
  .home-rules__grid {
    grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
    grid-template-areas: "nist nis2" "gdpr nis2";
    grid-template-rows: auto 1fr;
    column-gap: var(--gutter);
  }
  .home-rule:nth-child(1) { grid-area: nist; }
  .home-rule:nth-child(2) { grid-area: nis2; }
  .home-rule:nth-child(3) { grid-area: gdpr; align-self: start; border-top: 1px solid var(--line); }
}

/* for your compliance file: the control, the mapping, the evidence and the supplier facts (SU-10) */
.home-file {
  margin-top: var(--space-8);
}

.home-file__head > * + * {
  margin-top: var(--space-2);
}

.home-file__body {
  display: grid;
  gap: var(--space-6) var(--gutter);
  margin-top: var(--space-5);
  align-items: start;
}

@media (min-width: 48em) {
  .home-file__body { grid-template-columns: minmax(0, 14rem) minmax(0, 1fr); }
}

/* tablets: the facts column is narrow, so each label sits over its value */
@media (min-width: 48em) and (max-width: 63.999em) {
  .home-file__facts .kv > div { grid-template-columns: minmax(0, 1fr); }
}

@media (min-width: 64em) {
  .home-file__body { grid-template-columns: repeat(12, minmax(0, 1fr)); }
  .home-file__doc { grid-column: 1 / span 4; }
  .home-file__facts { grid-column: 5 / -1; }
}

/* the sample attestation's first page, linking the PDF (UI-11) */
.home-file__doc {
  display: grid;
  gap: var(--space-3);
  justify-items: start;
  color: var(--ink);
  text-decoration: none;
}

.home-file__doc img {
  width: 100%;
  max-width: 22.5rem;
  height: auto;
  border: 1px solid var(--line-2);
  border-radius: var(--r-md);
  background-color: var(--paper);
  transition: border-color 0.12s ease;
}

.home-file__doc:hover img {
  border-color: var(--ink-3);
}

/* a white document page glares on a dark page: take its brightness down a little */
:root[data-theme="dark"] .home-file__doc img {
  filter: brightness(0.88);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .home-file__doc img { filter: brightness(0.88); }
}

.home-file__doc-label {
  font-size: var(--text-sm);
  font-weight: 560;
  text-decoration-line: underline;
  text-decoration-thickness: 1px;
  text-decoration-color: var(--link-line);
  text-underline-offset: 0.2em;
}

.home-file__doc:hover .home-file__doc-label {
  text-decoration-thickness: 2px;
}

/* phones: a small thumbnail beside its label, so the facts follow at once */
@media not all and (min-width: 48em) {
  .home-file__doc {
    grid-template-columns: 7.5rem minmax(0, 1fr);
    align-items: center;
    column-gap: var(--space-4);
  }
}

.home-file__actions {
  margin-top: var(--space-5);
}


/* 8  Who runs PasswordRadar ================================================ */

.home-author {
  align-items: start;
}

.home-author__head > * + * {
  margin-top: var(--space-4);
}

/* one column until a real photo exists (then: auto minmax(0, 1fr), photo first) */
.home-author__card {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-5) var(--space-6);
}

.home-author__photo {
  width: 7rem;
  height: 7rem;
  border: 1px solid var(--line-2);
  border-radius: var(--r-lg);
  object-fit: cover;
}

.home-author__body {
  max-width: 40rem;
}

.home-author__body > * + * {
  margin-top: var(--space-3);
}

.home-author__body > p:first-of-type {
  margin-top: 0.125rem;
}

.home-author__facts {
  display: grid;
  gap: var(--space-2);
  margin-block: var(--space-4) 0;
  padding-left: 1.25rem;
  color: var(--ink-2);
}

.home-author__facts > li::marker {
  color: var(--ink-3);
}

.home-author__body blockquote {
  margin-block: var(--space-5);
}

.home-author__links {
  --cluster-gap: var(--space-2) var(--space-5);
  margin-top: var(--space-4);
  padding: 0;
  list-style: none;
}

.home-author__links a {
  display: inline-flex;
  align-items: center;
  min-height: 2.75rem;
}

/* the principles: title and one line each, no numbers (not a sequence). On desktop they sit under
   the heading, beside the person; the reading order stays heading, person, principles. */
.home-principles {
  margin-top: var(--space-7);
}

@media (min-width: 64em) {
  .home-author { grid-template-rows: auto 1fr; row-gap: var(--space-7); }
  .home-author__head { grid-column: 1 / span 5; grid-row: 1; }
  .home-author__card { grid-column: 6 / -1; grid-row: 1 / span 2; }
  .home-principles { grid-column: 1 / span 5; grid-row: 2; margin-top: 0; }
}

.home-principles__head > * + * {
  margin-top: var(--space-2);
}

.home-principles__head > p {
  max-width: var(--measure);
}

.home-principles__list {
  display: grid;
  gap: var(--space-4) var(--gutter);
  margin: var(--space-4) 0 0;
  padding: 0;
  list-style: none;
}

@media (min-width: 40em) and (max-width: 63.999em) {
  .home-principles__list { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

.home-principles__list > li {
  padding-top: var(--space-3);
  border-top: 1px solid var(--line);
}

.home-principles__list p {
  max-width: 30em;
  margin-top: var(--space-1);
  color: var(--ink-2);
  font-size: var(--text-sm);
  line-height: 1.55;
}


/* 9  Pricing =============================================================== */

.home-pricing__head {
  max-width: none;
}

.home-pricing__head > p {
  max-width: 36em;
}

.home-meter {
  display: grid;
  margin: var(--space-7) 0 0;
  border-block: 1px solid var(--line);
}

.home-meter > div {
  padding-block: var(--space-4);
}

.home-meter > div + div {
  border-top: 1px solid var(--line);
}

.home-meter dt {
  color: var(--ink-3);
  font-size: var(--text-xs);
  font-weight: 500;
  line-height: 1.4;
}

.home-meter dd {
  margin: 0.25rem 0 0;
  color: var(--ink);
  font-weight: 620;
  line-height: 1.4;
}

@media (min-width: 48em) {
  .home-meter { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1.2fr) minmax(0, 1.8fr); }
  .home-meter > div { padding-inline: var(--space-5); }
  .home-meter > div:first-child { padding-left: 0; }
  .home-meter > div + div {
    border-top: 0;
    border-left: 1px solid var(--line);
  }
}

/* SU-19: what the meter means for a real organisation */
.home-meter__example {
  max-width: var(--measure-wide);
  margin-top: var(--space-3);
}

.home-plans {
  display: grid;
  gap: var(--gutter);
  margin-top: var(--space-7);
}

@media (min-width: 64em) {
  .home-plans { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

.home-plan {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  border-color: var(--line-2);
}

.home-plan.panel > * + * {
  margin-top: 0;
}

.home-plan--tailored {
  border-color: var(--ink);
  box-shadow: inset 0 0 0 1px var(--ink);
}

.home-plan__top {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2) var(--space-3);
  min-height: 1.75rem;
}

/* no-JS landing spot for #apply: show the whole Tailored card, not just its heading */
#apply {
  scroll-margin-top: 2.75rem;
}

/* every price block is the same two lines, so the lists line up across the cards (UI-17) */
.home-plan__price {
  display: grid;
  row-gap: 0.25rem;
}

.home-plan__amount {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  font-family: var(--font-display);
  font-size: var(--text-4xl);
  font-weight: 780;
  font-stretch: 125%;
  line-height: 1;
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
}

.home-plan__from {
  color: var(--ink-2);
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  font-weight: 400;
  font-stretch: 100%;
  letter-spacing: 0;
}

.home-plan__per {
  color: var(--ink-2);
  font-size: var(--text-sm);
}

.home-plan__list {
  color: var(--ink-2);
  font-size: var(--text-sm);
  line-height: 1.5;
}

.home-plan__list a {
  color: var(--ink);
}

.home-plan__scale {
  padding-top: var(--space-4);
  border-top: 1px solid var(--line);
}

.home-plan.panel > .home-plan__action {
  display: grid;
  gap: var(--space-2);
  margin-top: auto;
  padding-top: var(--space-2);
}

.home-licence {
  max-width: var(--measure-wide);
  margin-top: var(--space-5);
}


/* 10  Roadmap: a real sequence, drawn as stations on one line ============== */

.home-roadmap {
  display: grid;
  gap: var(--space-7) var(--gutter);
  margin: var(--space-8) 0 0;
  padding: 0;
  list-style: none;
  counter-reset: road;
}

@media (min-width: 48em) {
  .home-roadmap { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (min-width: 64em) {
  .home-roadmap { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

.home-roadmap > li {
  position: relative;
  padding-top: var(--space-7);
  border-top: 1px solid var(--line-2);
  counter-increment: road;
}

.home-roadmap > li::before {
  content: counter(road);
  position: absolute;
  left: 0;
  top: -1.0625rem;
  display: grid;
  place-items: center;
  width: 2.125rem;
  height: 2.125rem;
  border: 1px solid var(--ink);
  border-radius: var(--r-md);
  background-color: var(--paper);
  color: var(--ink);
  font-family: var(--font-display);
  font-size: var(--text-md);
  font-weight: 720;
  font-stretch: 118%;
  font-variant-numeric: tabular-nums;
  line-height: 1;
}

.home-roadmap p {
  margin-top: var(--space-2);
  color: var(--ink-2);
}


/* 11  FAQ ================================================================== */

.home-faq {
  align-items: start;
}

.home-faq__head > * + * {
  margin-top: var(--space-4);
}

@media (min-width: 64em) {
  .home-faq__head {
    position: sticky;
    top: calc(var(--header-h) + var(--space-6));
  }
}


/* 12  Final call to action ================================================ */

.home-cta {
  align-items: end;
}

.home-cta__copy > * + * {
  margin-top: var(--space-5);
}

.home-cta__copy > p:not(.lede) {
  max-width: var(--measure);
  color: var(--ink-2);
}

.home-cta__actions {
  --cluster-gap: var(--space-3);
  margin-top: var(--space-6);
}


/* 13  Dialogs ============================================================== */

.home-key__step > * + *,
.home-partner__step > * + * {
  margin-top: var(--space-4);
}

.home-key__step .dialog__title:focus,
.home-partner__step .dialog__title:focus {
  outline: none;
}

/* form errors are role="alert" regions: home.js shows one empty, then adds its text, so it is
   announced every time. While empty it takes no room and shows no icon. */
.dialog .field__error:empty {
  position: absolute;
}

.dialog .field__error:empty::before {
  content: none;
}

/* the preview's status, next to its tag; also the dialog's description (UX-06) */
.home-key .dialog__head {
  flex-wrap: wrap;
}

.home-key__note {
  flex: 1;
  min-width: 0;
  margin-left: var(--space-1);
}

/* narrow phones: the note gets its own line under the tag, the close button stays top right */
@media not all and (min-width: 30em) {
  .home-key__note {
    order: 3;
    flex-basis: 100%;
    margin: var(--space-2) 0 0;
  }
}

/* the preview controls, grouped and named, and quieter than the real path (UX-06, UX-11) */
.home-key__preview {
  display: grid;
  gap: var(--space-3);
  min-width: 0;
  margin: 0;
  padding: 0;
  border: 0;
}

.home-key__preview > legend {
  float: left;
  width: 100%;
  margin-top: var(--space-2);
  padding: var(--space-4) 0 0;
  border-top: 1px solid var(--line);
  color: var(--ink-3);
  font-size: var(--text-xs);
  font-weight: 600;
  line-height: 1.4;
}

.home-key__option {
  display: grid;
  gap: 0.25rem;
  width: 100%;
  padding: 0.75rem 1rem;
  border: 1px solid var(--line-2);
  border-radius: var(--r-md);
  background-color: transparent;
  color: var(--ink);
  text-align: left;
  transition: border-color 0.12s ease, background-color 0.12s ease;
}

.home-key__option:hover {
  border-color: var(--ink-3);
  background-color: var(--paper);
}

.home-key__option-title {
  font-size: var(--text-sm);
  font-weight: 620;
}

.home-key__option-text {
  color: var(--ink-2);
  font-size: var(--text-xs);
  line-height: 1.5;
}

.home-key__form {
  --stack-gap: var(--space-3);
}

.home-key__links {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 0 var(--space-4);
}

.home-key__creds,
.home-partner__mail {
  display: grid;
  gap: var(--space-3);
  margin-block: var(--space-4) 0;
}

.home-key__creds dt,
.home-partner__mail dt {
  color: var(--ink-3);
  font-size: var(--text-xs);
  font-weight: 600;
}

.home-key__creds dd {
  margin: 0.25rem 0 0;
  padding: 0.5rem 0.75rem;
  border: 1px solid var(--line-2);
  border-radius: var(--r-md);
  background-color: var(--paper);
  font-size: 0.8125rem;
  word-break: break-all;
  user-select: all;
}

.home-partner__mail dd {
  margin: 0.125rem 0 0;
  font-size: var(--text-sm);
}

/* the address and its copy button on one row (UX-08) */
.home-partner__row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2) var(--space-3);
}

.home-partner__to {
  font-weight: 560;
}

.home-partner__body {
  max-height: 11rem;
  margin-top: 0.25rem;
  padding: 0.625rem 0.75rem;
  overflow: auto;
  border: 1px solid var(--line-2);
  border-radius: var(--r-md);
  background-color: var(--paper);
  color: var(--ink);
  font-size: 0.75rem;
  line-height: 1.6;
  white-space: pre-wrap;
  word-break: break-word;
}

.home-partner__copy-body {
  margin-top: var(--space-2);
}

.home-partner__copied {
  color: var(--clear);
  font-weight: 600;
}

.home-partner__copied:empty {
  margin-top: 0;
}


/* 14  Forced colours (Windows high contrast) ================================
   The mode drops backgrounds and shadows, and with them the scope's leaked and common returns,
   the legend's dot, the tag leaders, the beam and the pause toggle's pressed state: redraw them
   in system colours. Rings stay rings and dots stay dots. Every return is drawn at full strength
   (no afterglow fade, no flash), and the beam, the one moving part, takes the highlight colour. */
@media (forced-colors: active) {
  .home-mark--dot,
  .home-mark--ring,
  .home-contact__blip,
  .home-contact__tag::before,
  .home-scope__beam {
    forced-color-adjust: none;
  }
  .home-mark--dot,
  .home-contact__blip,
  .home-contact__tag::before {
    background-color: CanvasText;
  }
  .home-mark--ring,
  .home-contact--tailored .home-contact__blip {
    border-color: CanvasText;
    background-color: transparent;
  }
  .home-contact__blip {
    opacity: 1 !important;
  }
  .home-contact__blip::after {
    display: none;
  }
  /* the verdict's dot is a background in the word's colour, which forced colours would drop */
  .home-verdict__word::before {
    forced-color-adjust: none;
    background-color: CanvasText;
  }
  .home-scope__beam {
    background: Highlight;
  }
  /* no colour transition: it would pass through the page's own colours on the way */
  .home-scope__pause {
    transition: none;
  }
  .home-scope__pause[aria-pressed="true"] {
    forced-color-adjust: none;
    border-color: Highlight;
    background: Highlight;
    color: HighlightText;
  }
  .home-scope__pause[aria-pressed="true"]:focus-visible {
    outline-color: CanvasText;
  }
}
