/*
 * The marketing site's whole stylesheet. No framework and no build tooling: a
 * placeholder that needs a toolchain is a placeholder nobody replaces.
 *
 * It shares a visual language with the console — the same near-black ground and
 * the same accent — because U7 says the coupling between the two is a link and a
 * shared look, and nothing else.
 */

/* The faces, served from this site and nowhere else.
 *
 * Barlow is the brand face — material/word.svg is set in it — and the .woff2 files under
 * fonts/ are copies vendored out of the @fontsource packages the consoles bundle, so the
 * two surfaces render in the same metal. No Google Fonts link and no CDN: the site has to
 * come up on a host with no route out, and a stylesheet that reaches a third party for a
 * face also tells that third party who read the page.
 *
 * Copies are refreshed by re-running the copy out of frontend/node_modules/@fontsource;
 * nothing here is generated, which is why the file list is short and explicit.
 */
@font-face {
  font-family: Barlow;
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("./fonts/barlow-latin-400-normal.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212,
    U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: Barlow;
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("./fonts/barlow-latin-ext-400-normal.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304,
    U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0,
    U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: Barlow;
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("./fonts/barlow-latin-500-normal.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212,
    U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: Barlow;
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("./fonts/barlow-latin-ext-500-normal.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304,
    U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0,
    U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: Barlow;
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("./fonts/barlow-latin-600-normal.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212,
    U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: Barlow;
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("./fonts/barlow-latin-ext-600-normal.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304,
    U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0,
    U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: Barlow;
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("./fonts/barlow-latin-700-normal.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212,
    U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: Barlow;
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("./fonts/barlow-latin-ext-700-normal.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304,
    U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0,
    U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* Barlow Condensed is the wordmark's face. The wordmark itself ships as paths in brand/, so
   these are here for any text that has to sit beside it and match.

   THREE weights, because the wordmark is set in two of them: `Acme` light and `Alias` regular,
   which is what makes one word read as two parts without a colour change, a separator or a
   second size. 700 stays for anything else that has to match the artwork in brand/. */
@font-face {
  font-family: "Barlow Condensed";
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  src: url("./fonts/barlow-condensed-latin-300-normal.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212,
    U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Barlow Condensed";
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  src: url("./fonts/barlow-condensed-latin-ext-300-normal.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304,
    U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0,
    U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: "Barlow Condensed";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("./fonts/barlow-condensed-latin-400-normal.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212,
    U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Barlow Condensed";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("./fonts/barlow-condensed-latin-ext-400-normal.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304,
    U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0,
    U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: "Barlow Condensed";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("./fonts/barlow-condensed-latin-700-normal.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212,
    U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Barlow Condensed";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("./fonts/barlow-condensed-latin-ext-700-normal.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304,
    U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0,
    U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* The palette is the sign-in page's, deliberately and to the value: the same
 * black ground, the same #00ffb0 out of the logo, the same dark-grey panels. A
 * visitor crosses from here to auth.localhost mid-sentence, and the two surfaces
 * being one design is the only thing that makes that crossing unremarkable. The
 * blue that used to be the accent here belonged to the console's component
 * library rather than to us.
 *
 * The other copy of these values is development/authentik/branding/custom.css.
 * There is no mechanism keeping them in step — a shared file would have to be
 * served by both a static site and an identity provider that only reads its own
 * — so a change to one is a change to make twice, on purpose. */
:root {
  --ground: #05070a;
  --raised: #16191d;
  --raised-2: #1c2026;
  --line: rgb(255 255 255 / 12%);
  --ink: #fff;
  --ink-dim: rgb(255 255 255 / 62%);
  --accent: #00ffb0;
  --accent-bright: #4dffc9;
  --page: 62rem;
}

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  /* THE SAME FILE the sign-in page is lit by, not a CSS approximation of it.
   * brand/background.jpg is a copy of development/authentik/branding/flow_background.jpg
   * — black with a green wash off the top left and a cool specular under the
   * first screenful. Copied rather than shared because the two are served by
   * different things (busybox httpd here, authentik there) and neither can read
   * the other's directory; regenerate both together or they drift.
   *
   * `fixed` and `cover` so the light belongs to the window rather than to the
   * document: it stays put while the page scrolls, which is what stops the lower
   * half of a long page from looking like a different, unlit site. */
  background-color: var(--ground);
  background-image: url("./brand/background.jpg");
  background-size: cover;
  background-position: 50% 0;
  background-attachment: fixed;
  background-repeat: no-repeat;
  color: var(--ink);
  font-family: Barlow, -apple-system, "Segoe UI", "Helvetica Neue", Arial, sans-serif;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;

  /* The footer sits at the bottom of the VIEWPORT when the page is short, and at the
     bottom of the CONTENT when it is long.
     
     A placeholder page does not fill a screen, and a footer that stops halfway down
     leaves the rule under it floating in the middle of the window with lit background
     below — which reads as a page that failed to finish loading rather than as one that
     is simply short.

     Not `position: fixed`. That pins the footer over the content on every long page,
     costing a strip of the window forever to fix a problem only short pages have, and
     it takes the footer out of flow so the last paragraph slides underneath it. This
     keeps it in flow and lets the space above it grow instead. */
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

/* The one element allowed to absorb the slack. `flex: 1` on main is what pushes the
   footer down on a short page; on a long one main is already taller than the space and
   the rule does nothing. */
body > main {
  flex: 1 0 auto;
  /* And the same automatic-minimum trap once more, at the top of the tree: as a
   * flex item main takes a minimum of its own min-content, which is the widest
   * thing inside it — the comparison table, which deliberately sets 34rem so its
   * two columns stay readable. Without this the page below 592px is wider than
   * the window and every section scrolls sideways together; with it, main is the
   * window and the table alone scrolls inside its wrapper. */
  min-inline-size: 0;
}

code {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.9em;
  color: var(--accent);
  background: var(--raised-2);
  border: 1px solid var(--line);
  border-radius: 3px;
  padding: 0.05em 0.35em;
}

a {
  color: var(--accent);
}

/* Solid, and opaque on purpose: the bar is chrome, and chrome that the page's
 * lighting shows through reads as part of the content. It is the one band on the
 * page that is flat colour — everything below it sits on the gradient. */
.bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 1rem 1.5rem;
  background: var(--ground);
  border-block-end: 1px solid var(--line);
}

/* The brand mark is the artwork from material/, exported to paths so it needs no font at
 * render time, and served from this site — the same rule the faces follow. The two pieces
 * stay separate files because they are used apart: the glyph alone is the favicon, and the
 * wordmark alone is what a narrow bar keeps if the two ever have to split. */
.mark {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  text-decoration: none;
}

/* The logo keeps the height it had; the wordmark now has to match it as TYPE rather
 * than as a second image, which is a different problem: 1.9rem of box is not 1.9rem
 * of cap height. The font size is set to the value that puts the word's caps level
 * with the glyph's box, and the line-height to 1 so the box is the type and nothing
 * more. */
.mark-logo {
  block-size: 2rem;
}

.mark-word {
  font-family: "Barlow Condensed", Barlow, sans-serif;
  /* TWO weights in one word: `Acme` light, `Alias` regular. The pairing does the work a
   * separator or a second colour would otherwise do — the name reads as two parts while
   * staying one object, and nothing has to be drawn between them.
   *
   * 700 for the whole word was the previous setting, and at this size condensed bold is
   * heavier than the mark beside it: the eye landed on the WORD rather than on the glyph,
   * which is backwards for a bar whose only green thing is the mark. Dropping to 300/400
   * also let the size come down, because lighter type at the same measurement reads larger.
   *
   * Rejected: setting `Acme` in the accent green and `Alias` in white. It splits the name
   * into two colours, and the bar is allowed exactly one green thing. */
  font-weight: 400;
  /* Down from 2.25rem. The word no longer needs to be a shade taller than the glyph to hold
   * its own beside it — that compensation was for bold condensed caps, and at 300/400 the
   * word and the mark sit level. */
  font-size: 2rem;
  line-height: 1;
  letter-spacing: 0.005em;
  color: #fff;
  /* The bar is the one place a link is not the accent colour: white beside the
   * green mark, so the mark is what the eye lands on. */
  text-decoration: none;
}

/* The light half. A <span> rather than two sibling elements with a gap, so the word remains
 * one selectable, screen-reader-readable string: "AcmeAlias", not "Acme Alias". */
.mark-word b {
  font-weight: 300;
}

/* The one action the bar carries, and now filled rather than ghost-bordered — for
 * the same reason the sign-in page's `Log in` is filled: on black, one saturated
 * rectangle is where the eye goes, and this is where it should go. The label is
 * near-black on it because #00ffb0 is far too bright to carry white type; that is
 * a contrast fact, not a preference. */
.button {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.45rem 0.95rem;
  border: 1px solid transparent;
  border-radius: 4px;
  background: var(--accent);
  color: #05070a;
  font-weight: 600;
  text-decoration: none;
  line-height: 1;
}

.button:hover,
.button:focus-visible {
  background: var(--accent-bright);
  color: #05070a;
}

.icon {
  inline-size: 1em;
  block-size: 1em;
}

main {
  max-inline-size: var(--page);
  margin-inline: auto;
  padding: 0 1.5rem;
}

.hero {
  padding-block: clamp(3rem, 9vw, 6rem) 2rem;
}

.eyebrow {
  margin: 0 0 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  font-size: 0.75rem;
  color: var(--accent);
}

h1 {
  margin: 0 0 1rem;
  font-size: clamp(2rem, 5.5vw, 3.1rem);
  line-height: 1.08;
  letter-spacing: -0.025em;
  text-wrap: balance;
  max-inline-size: 22ch;
}

.lede {
  margin: 0;
  font-size: 1.1rem;
  color: var(--ink-dim);
  max-inline-size: 60ch;
}

/* The hero is two paragraphs now — the problem, then the shape of the answer —
   and they are two paragraphs precisely so the turn between them is visible.
   Run together they read as one long complaint. */
.lede + .lede {
  margin-block-start: 1rem;
}

.reasons ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr));
  gap: 1rem;
}

/* The one word to remember, over the sentence that earns it.

   Set like the hero's eyebrow — uppercase, tracked out, in the accent — so the three read as one
   set across the row rather than as three unrelated labels. Smaller than the hero's because it sits
   inside a panel and is competing with the heading directly below it rather than opening a page. */
.kicker {
  margin: 0 0 0.3rem;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  font-size: 0.7rem;
  font-weight: 500;
  color: var(--accent);
}

/* NOT numbered. The markers that used to sit here (01 / 02 / 03) were correct when this was a
   sequence — publishing the record has to happen before anything can follow it — and these are
   reasons, which have no order. A numbered marker is a structural claim about the content, so
   carrying it over would have been a false one kept for decoration. */
.reasons li {
  background: var(--raised);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 1.25rem;
  /* Lit from above and floating, the same two shadows the sign-in card uses. On
   * black a panel that is only a shade lighter needs the highlight to read as a
   * panel at all. */
  box-shadow:
    0 1px 0 rgb(255 255 255 / 6%) inset,
    0 18px 40px rgb(0 0 0 / 45%);
}

.reasons h2 {
  margin: 0 0 0.5rem;
  font-size: 1.05rem;
  letter-spacing: -0.01em;
}

.reasons p {
  margin: 0;
  color: var(--ink-dim);
}


/* A link with a <code> chip inside it. The underline runs beneath the chip's own
   background and box, which chops the descenders and makes one phrase read as
   three fragments. So the link carries its colour and an underline only on the
   words, and the chip inherits the link's colour instead of keeping the accent —
   two accents in one phrase is what made it look broken in the first place. */
.reasons a {
  text-decoration: none;
  border-block-end: 1px solid rgb(0 255 176 / 35%);
}

.reasons a:hover,
.reasons a:focus-visible {
  border-block-end-color: var(--accent-bright);
}

.reasons a code {
  color: inherit;
}

/* Every section below the reasons shares a rhythm: a heading, an optional lede at
   reading width, then the thing itself. Declared once so a new section joins the
   page rather than arriving with its own spacing. */
.proof,
.scope,
.pricing {
  padding-block: 3rem;
}

.proof h2,
.scope h2,
.pricing h2 {
  margin: 0 0 0.5rem;
  font-size: 1.35rem;
  letter-spacing: -0.01em;
}

.section-lede {
  margin: 0 0 1.5rem;
  color: var(--ink-dim);
  max-inline-size: 62ch;
}

/* A note UNDER a thing, tied to it by being tighter than the section gap. */
.note {
  margin: 1rem 0 0;
  color: var(--ink-dim);
  font-size: 0.95rem;
  max-inline-size: 62ch;
}

/* -- The integration, as a numbered sequence ------------------------------
 *
 * NUMBERED, unlike .reasons above, and for the opposite reason: those are
 * reasons and have no order, these are steps and have one. The marker is a
 * structural claim about the content in both cases — it is absent there because
 * it would be false, and present here because it is true. The failure this page
 * exists to prevent is somebody publishing the CNAME before the alias exists,
 * which is exactly a claim about order.
 *
 * A real <ol> with its marker suppressed and redrawn, rather than a <div> stack
 * with numbers typed in: a screen reader should announce "list, 6 items" and
 * each item's position, and hand-typed numerals go stale the first time a step
 * is inserted.
 */
.steps {
  list-style: none;
  margin: 0;
  padding: 0;
  counter-reset: step;
  display: grid;
  gap: 1rem;
}

.steps > li {
  counter-increment: step;
  position: relative;
  /* A GRID ITEM DEFAULTS TO min-width:auto, WHICH MEANS min-content, and the
   * min-content of a step holding a zone-file line or a dig transcript is that
   * line's full width — so one <pre> pushed the whole page wider than the
   * viewport and every section inherited the overflow. `.term` already scrolls;
   * this is what lets it. Found by measuring: at a 560px viewport the document
   * was 772px wide, and had been since before the steps existed. */
  min-inline-size: 0;
  background: var(--raised);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 1.25rem 1.25rem 1.25rem 4rem;
  box-shadow:
    0 1px 0 rgb(255 255 255 / 6%) inset,
    0 18px 40px rgb(0 0 0 / 45%);
}

/* The numeral sits in the padding reserved for it, so a step's prose starts on
 * one vertical line whether the marker is 1 or 6. */
.steps > li::before {
  content: counter(step, decimal-leading-zero);
  position: absolute;
  inset-block-start: 1.25rem;
  inset-inline-start: 1.25rem;
  font-variant-numeric: tabular-nums;
  font-size: 0.85rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  color: var(--accent);
}

.steps h3 {
  margin: 0 0 0.5rem;
  font-size: 1.05rem;
  letter-spacing: -0.01em;
}

.steps p {
  margin: 0;
  color: var(--ink-dim);
  max-inline-size: 68ch;
}

/* A step that carries a terminal block needs air above it; one that does not
 * must not gain a trailing gap. */
.steps .term {
  margin-block-start: 1rem;
}

.steps p + p,
.steps .term + p {
  margin-block-start: 0.75rem;
}

/* The note inside a step is subordinate to that step, not to the section, so it
 * loses the section note's top margin and keeps its smaller type. */
.steps .note {
  margin-block-start: 0.75rem;
}

/* The one-sentence version of a step. Present in the markup for every step and
 * hidden on a wide screen, where the full body is right there and a summary
 * above it would be the same thing said twice. */
.brief {
  display: none;
}

/* On a narrow screen the reserved gutter costs more than the alignment buys:
 * put the numeral on its own line above the heading instead.
 *
 * AND THE BODIES GO. Six steps carrying zone-file lines, a dig transcript and
 * nine client configurations is a wall on a phone: every one of those blocks is
 * monospace text with a minimum width, so it either overflows or shrinks to
 * unreadable, and the sequence — which is the thing this section exists to
 * teach — disappears under it. What survives is the numeral, the heading and one
 * sentence, so the whole integration is six lines a thumb can scroll past.
 *
 * The bodies are HIDDEN rather than deleted: this is a viewport rule, and the
 * same page on the same phone rotated, or read at a smaller text size, gets them
 * back. Anybody who is actually configuring something is at a keyboard, and the
 * page they open there is the full one.
 *
 * `> :not(h3, .brief)` rather than a class on each block, because the rule is
 * "the body of a step", and a rule that has to be maintained per element is one
 * somebody forgets the next time a step gains a paragraph. */
@media (max-width: 34rem) {
  .steps > li {
    padding-inline-start: 1.25rem;
    padding-block-start: 2.75rem;
  }

  .steps > li > :not(h3, .brief) {
    display: none;
  }

  .brief {
    display: block;
    margin: 0;
    color: var(--ink-dim);
  }

  /* The band would otherwise put four marks in a column of four rows and become
     the tallest thing on the page. Two by two, and smaller. */
  .logos {
    justify-content: center;
    gap: 1.25rem 1.75rem;
    padding: 1.25rem;
  }

  .logos img {
    block-size: 1.6rem;
  }

  .logos li.named {
    font-size: 1rem;
    gap: 0.45rem;
  }

  .logos li.named img {
    block-size: 1.8rem;
  }

  .logos li:nth-child(3) img {
    block-size: 1.9rem;
  }
}

/* -- The about page ------------------------------------------------------- */
.about {
  padding-block: 1rem 3rem;
  max-inline-size: 68ch;
}

.about h2 {
  margin: 2rem 0 0.5rem;
  font-size: 1.35rem;
  letter-spacing: -0.01em;
}

.about p {
  margin: 0 0 1rem;
  color: var(--ink-dim);
}

.about strong {
  color: var(--ink);
  font-weight: 600;
}

.help {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 1rem;
}

/* A rule down the side rather than a card each. These are four asks, not four
   offers, and the raised panel the feature cards use would give them the weight
   of things being sold. */
.help li {
  border-inline-start: 2px solid var(--line);
  padding-inline-start: 1rem;
  color: var(--ink-dim);
}

/* The imprint. A definition list because that is what it is — a set of labelled
   facts — and a screen reader announces the pairing, where two columns of divs
   would announce eight unrelated strings. */
.imprint {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 0.5rem 1.5rem;
  margin: 1rem 0 0;
  color: var(--ink-dim);
}

.imprint dt {
  color: var(--ink);
  font-weight: 500;
}

.imprint dd {
  margin: 0;
}

/* The pending fields are DIMMER, and they are also named. Colour alone would say
   "less important" to a reader who registers it and nothing at all to one who
   does not; the words say what is missing. */
.imprint dd.missing {
  opacity: 0.55;
  font-style: italic;
}

/* The one paragraph on the page that admits to a hole. Marked, so it does not
   read as finished copy somebody approved. */
.pending {
  margin-block-start: 2rem;
  padding: 0.85rem 1rem;
  border: 1px dashed var(--line);
  border-radius: 6px;
  font-size: 0.95rem;
}

/* -- The clients ----------------------------------------------------------
   A LIGHT BAND in a dark page, and that is the point rather than an accident.

   Four marks belonging to four other organisations, each used under its owner's
   guidelines — and every one of those guidelines assumes a light ground. Let's
   Encrypt publishes no reversed variant at all. Recolouring somebody's mark to
   suit our palette is the failure this strip used to avoid by carrying no marks,
   so the palette gives way for one band and gives it back afterwards.

   The band is white rather than near-white: a grey would read as a rendering
   fault beside four logos that each carry their own white. */
.clients {
  padding-block: 3rem;
}

.logos {
  list-style: none;
  margin: 1.5rem 0 0;
  padding: 1.75rem 2rem;
  background: #fff;
  border-radius: 10px;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem 2.5rem;
}

/* ONE OPTICAL HEIGHT, not one box height. A wordmark set on a 5:1 canvas and a
   square icon sized to the same height read as two different sizes, because the
   eye measures the ink and not the canvas — so the square one is stepped down
   and the long ones up until the row settles. These numbers were chosen by
   looking at the row, which is the only way this is ever decided. */
.logos img {
  display: block;
  inline-size: auto;
  block-size: 2rem;
}

/* cert-manager: a seal with no wordmark published anywhere, so the name is set
   beside it. Dark ink because this band is light, and the page's own face
   because that is what makes it a NAME rather than a forged logotype. */
.logos li.named {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  color: #16191d;
  font-size: 1.15rem;
  font-weight: 600;
  letter-spacing: -0.01em;
}

.logos li.named img {
  block-size: 2.3rem;
}

.logos li:nth-child(3) img {  /* certbot: a tall lockup, mark over nothing */
  block-size: 2.4rem;
}

/* The attribution under the band. Small, dim, and NOT hidden on narrow screens:
   it is the sentence that makes the use nominative rather than an implied
   endorsement, and a viewport is not a reason to stop saying it. */
.clients .note {
  margin-block-start: 1rem;
}

/* -- ...and the configurations, which now live inside step 5 ---------------
   Tabs, set the way the console's navigation is set (shell.component's `.nav`):
   a row of plain words over a rule, with the active one carrying an accent
   underline that COVERS the rule rather than sitting under it. Same product, so
   the control that means "pick one of these" should look the same in both
   places, and somebody who has used the console already knows what this is. */
.tablist {
  display: flex;
  flex-wrap: wrap;
  gap: 0 1.5rem;
  border-block-end: 1px solid var(--line);
  margin-block-end: 1.5rem;
}

/* Buttons and not links: these change what is displayed on this page, they do
   not navigate. A link here would offer a middle-click that opens nothing. */
.tablist button {
  appearance: none;
  background: none;
  border: 0;
  padding: 0.5rem 0;
  margin-block-end: -1px;
  border-block-end: 2px solid transparent;
  font: inherit;
  font-size: 0.95rem;
  color: var(--ink-dim);
  cursor: pointer;
}

.tablist button:hover {
  color: var(--ink);
}

.tablist button[aria-selected="true"] {
  color: var(--ink);
  border-block-end-color: var(--accent);
}

.tablist button:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 2px;
}

/* A minimum height, so switching between a six-line snippet and a two-line one
   does not move the rest of the page under the reader's cursor. */
.panels {
  min-block-size: 15rem;
}

.panels p {
  margin: 0 0 1rem;
  color: var(--ink-dim);
  max-inline-size: 62ch;
}

/* Without JavaScript every panel is shown, so they need separating from each
   other; with it, only one is ever visible and this never applies. */
.panels [role='tabpanel'] + [role='tabpanel'] {
  margin-block-start: 2rem;
}

/* ── The terminal ─────────────────────────────────────────────────────────────
   Deliberately not a screenshot. Text scales with the reader's font size, can be
   selected and pasted into their own shell — which is the entire point of the
   section, since a command they can run is the one claim on this page they do not
   have to take our word for — and it costs no image request.

   It scrolls sideways on a narrow screen rather than wrapping: a wrapped shell
   command reads as two commands, and the reader who most needs to copy it exactly
   is the one on a phone deciding whether to bother. */
.term {
  background: var(--raised);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 1.1rem 1.25rem;
  overflow-x: auto;
  box-shadow:
    0 1px 0 rgb(255 255 255 / 6%) inset,
    0 18px 40px rgb(0 0 0 / 45%);
}

.term pre {
  margin: 0;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.875rem;
  line-height: 1.7;
  color: var(--ink);
}

/* The prompt is dim and the OUTPUT is bright, which is the reverse of a real
   terminal and correct here: the reader is being shown an answer, not watching
   somebody type. */
.term .p {
  color: var(--ink-dim);
  user-select: none;
}

.term .o {
  color: var(--accent);
}

.term .c {
  color: var(--ink-dim);
}

/* ── What this is not ─────────────────────────────────────────────────────── */
.nots {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
  gap: 1rem;
}

/* No panel, no border. These are three denials, and dressing a denial in the same
   raised card the FEATURES use gives it the visual weight of an offer — the page
   would read as though not hosting your DNS were a product tier. A rule down the
   side is enough to group the words. */
.nots li {
  border-inline-start: 2px solid var(--line);
  padding-inline-start: 1rem;
}

.nots h3 {
  margin: 0 0 0.4rem;
  font-size: 1rem;
  letter-spacing: -0.01em;
}

.nots p {
  margin: 0;
  color: var(--ink-dim);
  font-size: 0.95rem;
}

/* ── The comparison ───────────────────────────────────────────────────────── */
.table-scroll {
  overflow-x: auto;
  /* AND A DEFINITE MAXIMUM, which is the half that actually holds. `overflow-x`
   * makes the table scroll INSIDE this box; it does not stop the box itself from
   * being sized by what it contains, so the 34rem minimum below still reached the
   * page and made every section 592px wide on a 380px phone. Measured before and
   * after: scrollWidth 592 → the viewport, at every width. */
  max-inline-size: 100%;
  /* AND the containment that makes the maximum bite. A scroll container is still
   * SIZED by its contents unless it is told not to be, and `max-inline-size:100%`
   * resolves against a parent that has itself already been widened by the same
   * contents — so the two rules together do nothing on their own. `contain:
   * inline-size` is what severs that: the box's inline size is computed as if it
   * were empty, the table lays out inside it at its 34rem minimum, and the
   * scrollbar appears. Measured at 500px: 592 → 500. */
  contain: inline-size;
  /* Same grid-item trap as `.steps > li`: the table below sets a 34rem minimum
   * so its two columns stay readable, and without this the scroller inherits
   * that as its own minimum and hands it to the page. With it, the table keeps
   * its minimum and SCROLLS, which is what the wrapper is for. */
  min-inline-size: 0;
}

.compare {
  inline-size: 100%;
  border-collapse: collapse;
  /* The two columns are equal so neither reads as the recommended one. A wider
     Team column would be an argument made in layout rather than in words. */
  table-layout: fixed;
  min-inline-size: 34rem;
}

.compare th,
.compare td {
  text-align: start;
  padding: 0.85rem 1rem;
  border-block-end: 1px solid var(--line);
  vertical-align: top;
}

/* Placed AFTER the rules above and not in the media block near the top of this
 * file, which is where it was first written and where it did nothing: same
 * specificity, and the base `min-inline-size` below is declared later in the
 * source, so it won. A media query is not a specificity boost. */
@media (max-width: 34rem) {
  /* THE COMPARISON STAYS A COMPARISON. The obvious mobile treatment is to stack
     the table into one card per row — and it destroys the only thing this
     section does, which is let somebody see both columns at once and notice
     that the technical rows are identical. A stacked table answers "what does
     Team have" one row at a time; nobody reads eighteen cells and holds them in
     their head. So the columns stay side by side and the TABLE gives way
     instead: no floor, tighter cells, smaller type.

     The 34rem floor is what keeps the columns readable on a desktop where there
     is room for it. Below this breakpoint there is no room, and a floor that
     produces a sideways scroll is worse than columns that are merely narrow —
     the scroll hides the Team column completely, which is the one somebody is
     reading the table to find out about. */
  .compare {
    min-inline-size: 0;
    font-size: 0.9rem;
  }

  .compare th,
  .compare td {
    padding: 0.6rem 0.4rem;
  }

  /* The price row's small print is the one thing that genuinely does not fit:
     two full sentences under a two-column price, in a column a third of a phone
     wide. It keeps its own line rather than its own column-width. */
  .compare .sub {
    font-size: 0.78rem;
    line-height: 1.35;
  }
}

.compare thead th {
  font-size: 1.05rem;
  letter-spacing: -0.01em;
  border-block-end-color: var(--accent);
}

/* The row labels are the question each row answers, so they are set like the body
   they sit beside rather than bolded into a second heading level. */
.compare tbody th {
  font-weight: 400;
  color: var(--ink-dim);
  inline-size: 34%;
}

.compare tbody tr:last-child th,
.compare tbody tr:last-child td {
  border-block-end: 0;
}

.row-price td strong {
  font-size: 1.25rem;
  color: var(--accent);
}

/* Under the number, not beside it: a cap and an expiry are conditions on a price,
   and a condition set at the same size as the price is a price with an asterisk. */
.sub {
  display: block;
  margin-block-start: 0.25rem;
  font-size: 0.85rem;
  color: var(--ink-dim);
}

/* A dash rather than a cross. Every empty cell here is about OTHER PEOPLE, and a
   cross reads as a failed test — as though the personal account had been measured
   against the team one and come up short, when a person working alone is missing
   nothing they would use. */
.compare .no {
  color: var(--ink-dim);
}

/* ── Sign up ──────────────────────────────────────────────────────────────
   Text on the left, the button opposite it on the right. Under the comparison,
   because the table is where "which of these am I" gets answered and the answer
   to both columns is the same button — a call to action three sections later
   would be asking somebody to remember a decision they already made.

   'space-between' with the button last puts it at the right edge without a
   margin auto on either element, so removing the text would not strand it. */
.signup {
  margin-block-start: 2rem;
  display: flex;
  align-items: center;
  /* flex-end, not space-between: the text that used to sit opposite the button went
     with the prices, and space-between on a single child is just flex-start. Restoring
     the parked pricing block (site/disabled/pricing.html) means putting this back. */
  justify-content: flex-end;
  gap: 2rem;
  flex-wrap: wrap;
}

.signup-text {
  /* Two short paragraphs at reading width. Tighter than the page's default
     leading, because these are conditions on the button beside them rather than
     prose somebody settles into. */
  display: grid;
  gap: 0.6rem;
  max-inline-size: 58ch;
  flex: 1 1 24rem;
}

.signup-text p {
  margin: 0;
  color: var(--ink-dim);
  font-size: 0.95rem;
  line-height: 1.5;
}

/* Never squeezed. On a narrow window the flex-wrap drops it to its own line at
   full size rather than compressing the one control on the page that matters. */
.signup .button {
  flex: 0 0 auto;
}

/* Visually gone, still announced. The comparison's caption and the dashes'
   meaning are both things a screen reader needs and a sighted reader gets from
   the layout. */
.sr-only {
  position: absolute;
  inline-size: 1px;
  block-size: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* The footer is chrome too, and closes the page the way the bar opens it. */
footer {
  background: var(--ground);
  border-block-start: 1px solid var(--line);
  margin-block-start: 2rem;
  padding: 2.25rem 1.5rem;
  /* Never compressed to fit. Without this a flex parent may shrink the footer on a
     viewport shorter than its content, which crops the very line it exists to carry. */
  flex-shrink: 0;
}

/* The footer holds the links and nothing else now.
 *
 * It used to carry a paragraph saying the site was a placeholder and naming the
 * change that lists what it still owes. That was honest and it was addressed to
 * US: a visitor reading "this page exists so the hostname and its build are
 * real" learns that we have not finished, on the page that is supposed to make
 * them trust us with their DNS. What the site owes — imprint, privacy, terms,
 * abuse contact — is tracked in public-edition 8.5-8.8, which is where it
 * belongs, and its absence is visible there rather than announced here.
 *
 * The vertical padding replaces it. Without something the footer collapses to a
 * rule with two links against it, which reads as the page having been cut off
 * rather than ended. */
.foot-nav {
  display: flex;
  gap: 1.25rem;
  max-inline-size: var(--page);
  margin-inline: auto;
  font-size: 0.9rem;
}

footer p {
  max-inline-size: var(--page);
  margin-inline: auto;
  color: var(--ink-dim);
  font-size: 0.9rem;
}
