/*
 * sikkerfil — carried over from the 2020 site.
 *
 * The brand is already decided: League Gothic, and the colours out of the
 * logo. Those values are reused exactly rather than re-picked — when the
 * wordmarks were redrawn in 2026 the palette moved with them, from the old
 * #255084/#4d8bd3 blues to the mark's navy, slate and teal, because a site
 * whose chrome disagrees with its own logo reads as unfinished to exactly the
 * compliance buyer plan.md §2 is written for.
 *
 * The teal (#248793) is the one genuinely new role. It is the only colour in
 * the mark that is not a blue, which makes it the only one that can carry a
 * primary action without the page turning monochrome.
 *
 * ONE DEPARTURE FROM THE ORIGINAL, and it is deliberate. The 2020 stylesheet
 * set League Gothic on `*`, so every word on the page was in a condensed
 * display face. That is right for the wordmark and headings and wrong for the
 * things this service now has to say — an expiry warning, a "your key is in the
 * link and we cannot recover it" notice, a file size. Condensed faces at small
 * sizes are measurably harder to read, and the copy that matters most here is
 * the copy a user must not skim. So League Gothic is the display face and body
 * text is a system stack.
 */

@font-face {
  font-family: "League Gothic";
  src: url("/a/league-gothic.c2fe7081.woff") format("woff");
  font-weight: normal;
  font-style: normal;
  /* swap, so the page is readable before a 24kb font arrives. The layout shift
     is worth less than the delay. */
  font-display: swap;
}

:root {
  --ink: #122f4b;
  --ink-bright: #4a789f;
  /* TWO TEALS, because one cannot do both jobs. #248793 is the logo's own and
     is right as a shape beside the mark, but on white it is 4.2:1 — under AA
     for text and for a button label. --accent-ink is the same hue darkened
     until it passes (6.2:1), and is what anything carrying WORDS uses. A
     service that sells an auditable trail should not ship a trust page a DPO
     cannot read. */
  --accent: #248793;
  --accent-ink: #1a6a74;
  --chrome: #42576f;
  --paper: #ffffff;
  --paper-sunk: #f4f7fb;
  --line: #d6e2f2;
  --muted: #5b6b80;
  --warn: #8a5a00;
  --warn-bg: #fff8e6;
  --bad: #a3282d;
  --text: #1d2733;
  /* Revoking is destructive and reads in a different red from an error
     message. It is a token rather than a literal so that its dark value lives
     with the rest of the dark palette instead of in a third media query that
     the theme override would not reach. */
  --revoke: #b3261e;
  --sunk-tint: rgba(37, 80, 132, 0.06);

  /* So the scrollbar, the form controls and the canvas the browser paints
     before our CSS arrives all follow the theme rather than only our own
     backgrounds doing so. */
  color-scheme: light;

  /* A surface that sits ON the page rather than floating in it, and a rim
     light to separate the two. Stated once so a card, a dropzone and a footer
     cannot each invent their own. */
  --radius: 12px;
  --radius-lg: 16px;
  --shadow: 0 1px 2px rgba(18, 47, 75, 0.06), 0 8px 24px rgba(18, 47, 75, 0.07);
  --shadow-lift: 0 2px 4px rgba(18, 47, 75, 0.08), 0 14px 34px rgba(18, 47, 75, 0.12);

  --display: "League Gothic", "Haettenschweiler", "Arial Narrow", sans-serif;
  --body: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue",
    Arial, sans-serif;
}

/* The original was light-only. A dark scheme is not invented here — these are
   the same hues at a lightness that works on a dark ground, so the brand is
   recognisably itself either way.

   TWO BLOCKS, IDENTICAL BY OBLIGATION. The first is the default: the reader's
   system asked for dark and they have not overridden it. The second is the
   override itself. CSS cannot apply one declaration block to both a media
   query and a selector, so the values are written twice — and app.css.test.ts
   parses this file and fails if the two ever stop agreeing, because a palette
   that drifts between "dark because your phone is" and "dark because you asked"
   is a bug nobody would think to look for. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --ink: #9dc2ee;
    --ink-bright: #7fb0e8;
    /* Lifted off the logo's #248793, which on this ground is legible as a
       shape but not as a word. At 7.2:1 against --paper the lifted one carries
       text too, so dark mode needs only the one. */
    --accent: #45b3c0;
    --accent-ink: #45b3c0;
    --chrome: #16304f;
    --paper: #10161f;
    --paper-sunk: #161f2b;
    --line: #2a3849;
    --muted: #93a3b8;
    --warn: #e8b552;
    --warn-bg: #2b2313;
    --bad: #f08c90;
    --text: #e6edf5;
    --revoke: #ff8a80;
    --sunk-tint: rgba(255, 255, 255, 0.06);
    /* Shadows do almost nothing on a dark ground — depth there comes from the
       surface being LIGHTER than the page, which --paper-sunk already is. What
       is left is a rim, so a card still has an edge. */
    --shadow: 0 0 0 1px rgba(255, 255, 255, 0.04);
    --shadow-lift: 0 0 0 1px rgba(255, 255, 255, 0.10);
  }
}

:root[data-theme="dark"] {
  color-scheme: dark;
    --ink: #9dc2ee;
    --ink-bright: #7fb0e8;
    /* Lifted off the logo's #248793, which on this ground is legible as a
       shape but not as a word. At 7.2:1 against --paper the lifted one carries
       text too, so dark mode needs only the one. */
    --accent: #45b3c0;
    --accent-ink: #45b3c0;
    --chrome: #16304f;
    --paper: #10161f;
    --paper-sunk: #161f2b;
    --line: #2a3849;
    --muted: #93a3b8;
    --warn: #e8b552;
    --warn-bg: #2b2313;
    --bad: #f08c90;
    --text: #e6edf5;
    --revoke: #ff8a80;
    --sunk-tint: rgba(255, 255, 255, 0.06);
    /* Shadows do almost nothing on a dark ground — depth there comes from the
       surface being LIGHTER than the page, which --paper-sunk already is. What
       is left is a rim, so a card still has an edge. */
    --shadow: 0 0 0 1px rgba(255, 255, 255, 0.04);
    --shadow-lift: 0 0 0 1px rgba(255, 255, 255, 0.10);
}

* {
  box-sizing: border-box;
}

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

body {
  font-family: var(--body);
  color: var(--text);
  background: var(--paper);
  line-height: 1.5;
  /* So a short page still puts the footer at the bottom of the viewport
     instead of leaving it floating halfway up with blank space beneath. */
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

/* The 2020 rule was `width: 50%`, which on a phone is a 190px column. Same
   intent — a centred, comfortable measure — expressed so it survives a narrow
   viewport. */
.container {
  width: 100%;
  max-width: 44rem;
  margin: 0 auto;
  padding: 0 1rem;
}

/* Takes up the slack in the body's column, which is what pushes the footer to
   the bottom of a short page rather than leaving it mid-screen. */
main {
  flex: 1;
}

header {
  text-align: center;
  padding: 1rem 0 1.5rem;
}

/* The account corner, now at the top. Aligned to the same measure as the
   content rather than the full width, so it sits over the column it belongs to
   instead of out at the window edge. */
.account-bar {
  width: 100%;
  max-width: 44rem;
  margin: 0 auto 1.5rem;
  padding: 0 1rem;
  display: flex;
  justify-content: flex-end;
  font-size: 0.9rem;
}

/* A CONTROL, NOT A STRAY UNDERLINE. "Logg inn" was a bare link floating in the
   corner of an otherwise empty band, which is how it read: like something left
   over rather than the way in. A bordered pill says it can be pressed, without
   competing with the primary action further down the page — that one is filled,
   this one is outlined, and the difference is the hierarchy. */
.account-bar a,
.account-bar button {
  display: inline-flex;
  align-items: center;
  min-height: 2.25rem;
  padding: 0.35rem 0.9rem;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--paper);
  color: var(--accent-ink);
  font-size: 0.9rem;
  font-family: var(--body);
  letter-spacing: 0;
  text-decoration: none;
  box-shadow: none;
  transition: border-color 0.15s ease, background 0.15s ease;
}

.account-bar a:hover,
.account-bar button:hover:not(:disabled) {
  border-color: var(--accent);
  background: var(--paper-sunk);
  box-shadow: none;
  opacity: 1;
}

/* The address is who you are, not a thing to press, so it reads quieter than
   the control beside it — but it stays a link, because it is the only route to
   the dashboard. */
#account-email {
  opacity: 1;
  color: var(--text);
  border-color: transparent;
  background: none;
}

#account-email:hover {
  border-color: var(--line);
}

/* The mark is the way home. inline-block so the link box is the image itself
   and shrink-wraps it — giving the link its own width would leave the narrower
   phone variant sitting off-centre inside a 300px box. */
.home {
  display: inline-block;
}

/* aspect-ratio rather than width/height attributes, because <picture> serves
   two different shapes from one <img> and the attributes can only describe one
   of them. Without this the header reflows when the logo lands, which is the
   worst place on the page for it — it is the first thing above the fold.
   The breakpoint matches the one in pages.ts; they have to agree, and the
   markup is the one that decides which file is actually fetched. */
header img {
  width: 100%;
  /* 300px of stacked mark put the first line of content most of a screen down.
     The logo is still the largest thing on the page, which is right, but it no
     longer has to be the only thing above the fold. */
  max-width: 220px;
  height: auto;
  aspect-ratio: 915 / 842;
}

@media (max-width: 37.5rem) {
  header {
    padding: 2rem 0 1rem;
  }

  header img {
    max-width: 260px;
    aspect-ratio: 1530 / 535;
  }
}

.tagline {
  font-family: var(--display);
  font-size: 1.75rem;
  letter-spacing: 0.02em;
  color: var(--ink);
  margin: 0.5rem 0 0;
}

h1,
h2 {
  font-family: var(--display);
  color: var(--ink);
  letter-spacing: 0.02em;
  margin: 0 0 0.5rem;
}

h1 {
  font-size: 2.25rem;
}

h2 {
  font-size: 1.5rem;
}

/* The drop target. Dropzone.js is gone — the client encrypts before uploading
   (plan.md §6.2), so the upload cannot be handed to a library that posts the
   file as it is — but the shape it presented is kept. */
.dropzone {
  /* BOTH OF THESE ARE LOAD-BEARING and their absence broke the page.
     A <label> is inline by default, and an inline box's padding does not
     affect line height — so `padding: 3rem 1.5rem` below rendered as a dashed
     border bleeding OUTSIDE the flow without reserving any space for itself.
     The result: the border fragmented across line boxes, the zone started
     above its own form, and the first field sat on top of it.
     `.field label` has always had display: block; this one was simply missed.

     position: relative is the companion to the visually-hidden file input
     below, which is position: absolute. Without a positioned ancestor it
     resolves against the initial containing block — harmless while it is 1px
     and clipped, wrong the moment either changes. */
  display: block;
  position: relative;
  border: 2px dashed var(--line);
  border-radius: var(--radius-lg);
  background: var(--paper-sunk);
  padding: 3.25rem 1.5rem;
  text-align: center;
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease;
}

.dropzone:hover,
.dropzone:focus-visible,
.dropzone.is-over {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 6%, var(--paper-sunk));
}

/* Dragging a file over it should feel like it has been caught. */
.dropzone.is-over {
  border-style: solid;
  box-shadow: var(--shadow-lift);
}

.dropzone .prompt {
  font-family: var(--display);
  font-size: 1.75rem;
  color: var(--ink);
  display: block;
}

.dropzone .hint {
  color: var(--muted);
  font-size: 0.9rem;
}

/* The file input is .sr-only in the markup: hidden but still focusable and
   still announced, so the keyboard and screen-reader path is this same control
   rather than a second one. */

.field {
  margin: 1rem 0;
}

.field label {
  display: block;
  font-weight: 600;
  font-size: 0.9rem;
  margin-bottom: 0.25rem;
}

/* A FIELD YOU CAN SEE AND HIT. The 2020 rule produced a 30-pixel box with a
   hairline round it, which on the sign-in page — where the field IS the page —
   read as an afterthought. 44px is the smallest target a thumb reliably hits,
   and the measure is capped because a single email field stretched across a
   desktop looks broken, not generous. */
input[type="text"],
input[type="email"],
input[type="password"],
input[type="number"],
select {
  width: 100%;
  max-width: 26rem;
  min-height: 2.75rem;
  padding: 0.65rem 0.85rem;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  font: inherit;
  font-size: 1rem;
  background: var(--paper);
  color: inherit;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

input[type="text"]:hover,
input[type="email"]:hover,
input[type="password"]:hover,
input[type="number"]:hover,
select:hover {
  border-color: var(--ink-bright);
}

/* THE FOCUS RING IS THE BRAND'S, not the browser's default blue, and it is a
   ring rather than an outline so it follows the radius. :focus-visible so a
   mouse click does not light it up — a keyboard user needs this and a pointer
   user has already been told where they are by the caret. */
input[type="text"]:focus-visible,
input[type="email"]:focus-visible,
input[type="password"]:focus-visible,
input[type="number"]:focus-visible,
select:focus-visible {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 28%, transparent);
}

/* Everything else focusable gets a visible ring too. The site had none and
   relied on whatever the browser drew, which on a dark page is often nothing. */
a:focus-visible,
button:focus-visible,
.dropzone:focus-visible,
summary:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 4px;
}

/* The teal, not the navy. It is the only colour in the mark that is not a
   blue, so it is the only one that can mark the primary action without the
   page going monochrome — and the navy is now dark enough that a button in it
   reads as disabled chrome rather than as the thing to press. */
button {
  font-family: var(--display);
  font-size: 1.4rem;
  letter-spacing: 0.02em;
  background: var(--accent-ink);
  color: #fff;
  border: 0;
  border-radius: var(--radius);
  padding: 0.6rem 1.9rem;
  min-height: 2.75rem;
  cursor: pointer;
  box-shadow: var(--shadow);
  transition: background 0.15s ease, box-shadow 0.15s ease, transform 0.08s ease;
}

button:hover:not(:disabled) {
  background: var(--accent);
  box-shadow: var(--shadow-lift);
}

/* One pixel, on press. Enough to feel like a button and not enough to shift
   anything around it. */
button:active:not(:disabled) {
  transform: translateY(1px);
  box-shadow: var(--shadow);
}

button:disabled {
  opacity: 0.55;
  cursor: default;
  box-shadow: none;
}

.progress {
  height: 14px;
  border: 1px solid var(--line);
  border-radius: 7px;
  overflow: hidden;
  background: var(--paper-sunk);
}

.progress > span {
  display: block;
  height: 100%;
  width: 0;
  background: var(--ink-bright);
  transition: width 0.2s ease;
}

/* The link and the button that copies it, on one line — and wrapping to two on
   a narrow phone rather than squeezing a monospace URL into half a screen. */
.link-row {
  display: flex;
  align-items: stretch;
  gap: 0.5rem;
  flex-wrap: wrap;
  margin: 0.5rem 0 1rem;
}

.link-out {
  flex: 1 1 18rem;
  /* The measure cap on other inputs is wrong here: this is a URL to be read
     back or copied, not a field to type into, so it takes the width it has. */
  max-width: none;
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  font-size: 0.95rem;
}

#copy {
  flex: 0 0 auto;
  font-size: 1.1rem;
  padding: 0.5rem 1.25rem;
}

/* The notice that carries plan.md §6.2's cost. It is styled to be read rather
   than to be pretty: if a user skims past this, they lose a file and we cannot
   help them. */
.notice {
  background: var(--warn-bg);
  border-left: 4px solid var(--warn);
  color: var(--warn);
  padding: 1rem 1.25rem;
  border-radius: 0 var(--radius) var(--radius) 0;
  margin: 1rem 0;
  font-size: 0.95rem;
}

.notice h2 {
  color: inherit;
  margin-top: 0;
}

.error {
  color: var(--bad);
  font-weight: 600;
}

.meta {
  list-style: none;
  padding: 0;
  margin: 1rem 0;
  border-top: 1px solid var(--line);
}

.meta li {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.5rem 0;
  border-bottom: 1px solid var(--line);
  font-size: 0.95rem;
}

.meta li span:first-child {
  color: var(--muted);
}

[hidden] {
  display: none !important;
}

/* An ordinary footer at the end of the document.
   The 2020 design had it FIXED, and it was carried over that way without the
   question being asked. A bar pinned across the bottom of every page costs a
   phone a permanent strip of its screen, covers the last line of whatever you
   are reading, and follows you down a long page like a cookie banner. The
   residency line does not need to be in front of you at all times; it needs to
   be somewhere obvious, which the end of the page is.
   The residency line is in it deliberately: plan.md §3 says residency should be
   demonstrable, and the cheapest version of that is saying it on every page. */
.footer {
  margin-top: 4rem;
  padding: 1rem;
  background: var(--chrome);
  color: #fff;
  text-align: left;
  font-size: 0.85rem;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
  flex-wrap: wrap;
}

.footer a {
  color: #fff;
}

/* The theme control. Styled as the footer's own text rather than as a button,
   for the same reason the sign-out control is: a 40-pixel blue button down here
   would shout over the residency line, which is the sentence this footer exists
   to carry. */
/* A visually-hidden utility. The file input inside the dropzone has carried its
   own copy of this since the first commit; the radios below need the same, and
   two copies of a clip rectangle is one too many. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* THE COLOUR THEME, as three segments on the footer's chrome.
   It was an underlined word, which reads as a link — and a link that does not
   navigate is the most confusing thing a footer can hold. Segments show all
   three states at once, so the one that is on is visible without pressing
   anything, and "follow the system" stays somewhere a reader can get back to. */
.theme {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  padding: 2px;
  border: 1px solid rgba(255, 255, 255, 0.35);
  border-radius: 999px;
}

.theme-option {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* 28px rather than the 44px a standalone target would get: three of those in
     a footer is a toolbar, and these sit inside one control that is itself
     comfortably large. */
  width: 28px;
  height: 28px;
  border-radius: 999px;
  color: #fff;
  opacity: 0.6;
  cursor: pointer;
  transition: background 0.15s ease, opacity 0.15s ease;
}

.theme-option:hover {
  opacity: 1;
  background: rgba(255, 255, 255, 0.14);
}

/* The chosen segment. Filled rather than merely brighter, because "which one is
   on" has to survive being glanced at. */
.sr-only:checked + .theme-option {
  opacity: 1;
  background: rgba(255, 255, 255, 0.24);
}

/* The input is off-screen, so the ring has to be drawn on the label it drives —
   otherwise keyboard focus lands somewhere nobody can see. */
.sr-only:focus-visible + .theme-option {
  outline: 2px solid #fff;
  outline-offset: 2px;
  opacity: 1;
}

.theme-option svg {
  display: block;
}

/* The receipt (plan.md §2 "Prove"). Deliberately plain: this is evidence
   somebody forwards to a data protection officer, not a dashboard. It reuses
   .meta for the trail itself so a receipt and a share page look like the same
   product. */
.download-csv {
  color: var(--ink);
  font-weight: 600;
  cursor: pointer;
}

.download-csv:hover {
  color: var(--ink-bright);
}

.receipt-note {
  color: var(--muted);
  font-size: 0.9rem;
  border-top: 1px solid var(--line);
  padding-top: 0.75rem;
}

/* The account corner. It reads in the action colour rather than the browser's
   default blue, and that is not decoration: this bar used to sit on the
   footer's --chrome and its text was #fff, which on --paper is a corner that
   renders as nothing at all. */
.account a,
#signout {
  color: var(--accent-ink);
}

/* The account corner, in the header above the content.

   In the footer rather than the header on purpose: the header is the logo and
   the promise, and this product's first job is "drop a file here" for somebody
   who has never signed in and does not need to. An account is how you get your
   files BACK, which is a second visit's concern. The three items occupy the
   same slot and the client shows one — see paintAccountCorner in app.ts, and
   note that it has to ask the API because this shell is cached at the edge for
   everyone alike. */
.account {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

/* A button that reads as a link, because it sits in a line of text beside one.
   It stays a <button> rather than becoming an <a>: signing out is an action
   with a side effect, not a destination, and the CSP says form-action 'none'. */
/* Written as .account-bar #signout so it does not have to fight the pill rules
   above it. An ID selector beats a class one, so the plain-link version of this
   silently won and "Logg ut" stayed a bare underline in a row of controls. */
.account-bar #signout {
  font-family: var(--body);
  font-size: 0.9rem;
  text-decoration: none;
  margin: 0;
  cursor: pointer;
}



/* THE CARD. The sign-in form and the upload options were laid straight onto
   white: a label, a hairline box and a button, with nothing holding them
   together. A surface with a rim and a shadow says "this is the thing to fill
   in" before a word of it is read, which on a page with one field on it is the
   whole job.
   --paper-sunk rather than a tint of the brand: the card should recede and let
   the control in it come forward, and a coloured panel does the opposite. */
.card {
  background: var(--paper-sunk);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
  padding: 1.5rem;
  margin: 1.5rem 0;
}

/* The hint under a field, which the .dropzone rule already styles for its own
   use — outside it, it needs to be a block or it sits on the same line as the
   control above it. */
.field .hint {
  display: block;
  margin-top: 0.35rem;
  color: var(--muted);
  font-size: 0.85rem;
}

/* The last field in a card should not push the rim away from itself. */
.card > .field:last-child,
.card > p:last-child {
  margin-bottom: 0;
}

/* The sign-in page. One narrow column: there is one field on it and nothing
   else to look at. */
#signin {
  max-width: 26rem;
}

/* The dashboard (plan.md §10 Phase 3c).

   Cards rather than a table, because the interesting thing about a share is
   four short facts and two actions, and a table of four columns on a phone is
   four columns too many. It reuses .meta so a dashboard row, a share page and
   a receipt all look like the same product. */
.shares {
  list-style: none;
  padding: 0;
  margin: 0;
}

.share {
  border: 1px solid var(--line);
  border-radius: 4px;
  padding: 1rem 1.25rem;
  margin-bottom: 1rem;
}

/* The id is the only handle on a share the dashboard can show — the filename
   is encrypted under a key we never had. Monospace because it is an
   identifier somebody may read aloud or type. */
.share-id {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 1.05rem;
  letter-spacing: 0.06em;
  margin: 0 0 0.5rem;
}

.share .meta {
  margin: 0 0 0.75rem;
}

.share-actions {
  display: flex;
  align-items: center;
  gap: 1.25rem;
  margin: 0;
}

/* Destructive, so it reads as destructive — but not a red slab, because it
   sits next to an ordinary link and the page is not trying to frighten
   anybody. The confirm() before it is what actually prevents the accident. */
.revoke {
  background: none;
  border: none;
  padding: 0;
  margin: 0;
  min-height: 0;
  font-family: inherit;
  font-size: inherit;
  color: var(--revoke);
  text-decoration: underline;
  cursor: pointer;
}

.revoke:hover:not(:disabled) {
  background: none;
  opacity: 0.75;
}

/* The sign-in prompt where the dropzone would be. A button rather than a bare
   link: on the upload page it is the only thing to do. */
/* The same decision as `button`, for the anchor that looks like one. */
.cta {
  display: inline-block;
  background: var(--accent-ink);
  color: #fff;
  padding: 0.6rem 1.4rem;
  border-radius: 4px;
  text-decoration: none;
  font-weight: 600;
}

.cta:hover {
  background: var(--accent);
  color: #fff;
}

/* The DPO page (plan.md §2). Long-form prose, so it gets a measure a person
   can actually read — around 70 characters — rather than the full container
   width the forms use. */
.lede {
  font-size: 1.1rem;
  color: var(--muted);
}

main h2 {
  margin-top: 2.25rem;
}

main p {
  max-width: 38rem;
  line-height: 1.6;
}

ul.plain {
  max-width: 38rem;
  line-height: 1.6;
  padding-left: 1.2rem;
}

ul.plain li {
  margin-bottom: 0.4rem;
}

/* The retention table. A real <table> because it is tabular data that somebody
   will print or paste into a procurement document, and because a screen reader
   should announce it as one. */
.retention {
  border-collapse: collapse;
  max-width: 38rem;
  width: 100%;
  margin: 1rem 0 0;
}

.retention th,
.retention td {
  text-align: left;
  padding: 0.5rem 0.75rem 0.5rem 0;
  border-bottom: 1px solid var(--line);
  vertical-align: top;
}

.retention th {
  font-family: "League Gothic", var(--display), sans-serif;
  font-size: 1.15rem;
  letter-spacing: 0.02em;
}

/* Printed and attached to a ticket is a first-class use of this page, so the
   chrome that helps on screen only gets in the way on paper. */
@media print {
  .footer,
  .account-bar,
  header picture {
    display: none;
  }

  main p,
  ul.plain,
  .retention {
    max-width: none;
  }
}

/* The named link field. The prefix sits outside the input so what the sender
   types is exactly what gets claimed — a field pre-filled with "sikkerfil.no/"
   is a field people paste a whole URL into. */
.named-link {
  display: flex;
  align-items: stretch;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  max-width: 26rem;
  min-height: 2.75rem;
  background: var(--paper);
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.named-link:hover {
  border-color: var(--ink-bright);
}

/* The ring goes on the WHOLE control, not on the input inside it — the prefix
   is part of the same field and a ring round half of it looks broken. */
.named-link:focus-within {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 28%, transparent);
}

.named-prefix {
  display: flex;
  align-items: center;
  padding: 0 0.1rem 0 0.75rem;
  background: var(--sunk-tint);
  color: var(--muted);
  white-space: nowrap;
  font-size: 0.95rem;
}

.named-link input {
  border: none;
  border-radius: 0;
  flex: 1;
  min-width: 0;
  max-width: none;
  min-height: 0;
  background: none;
}

.named-link input:focus-visible {
  outline: none;
  box-shadow: none;
}


/* The footer's own pages ---------------------------------------------------
   A row, not a column: two links wrapping to one per line on a narrow screen
   rather than overflowing. The separator is DRAWN between items rather than
   typed into the markup, so adding or removing a link cannot leave a stray dot
   behind — which is the failure mode of every hand-punctuated nav. */
.footer-links {
  display: flex;
  flex-wrap: wrap;
  gap: 0.2rem 0.9rem;
}

.footer-links a + a {
  position: relative;
}

.footer-links a + a::before {
  content: "·";
  position: absolute;
  left: -0.55rem;
  /* On the footer's dark chrome, so not var(--line). */
  opacity: 0.5;
}

/* The business and developer pages -----------------------------------------
   Both are documents rather than forms, and the column the app's controls live
   in is too narrow for a reference with a three-column table in it. Widening
   main for everybody would loosen the pages that are already right, so this is
   scoped to the two that need it. */
.price {
  font-family: "League Gothic", var(--display), sans-serif;
  font-size: 1.6rem;
  letter-spacing: 0.02em;
  margin: 0.3rem 0 0.6rem;
}

/* The endpoint table. Tabular for the same reason the retention table is: it is
   a reference somebody scans down a column of, not prose. */
.endpoints {
  border-collapse: collapse;
  width: 100%;
  margin: 0.5rem 0 0;
  font-size: 0.95rem;
}

.endpoints th,
.endpoints td {
  text-align: left;
  padding: 0.5rem 0.9rem 0.5rem 0;
  border-bottom: 1px solid var(--line);
  vertical-align: top;
}

.endpoints th {
  font-family: "League Gothic", var(--display), sans-serif;
  font-size: 1.15rem;
  letter-spacing: 0.02em;
}

.endpoints .need {
  color: var(--muted);
  white-space: nowrap;
}

.method {
  font-weight: 600;
  color: var(--accent-ink);
}

.path {
  white-space: nowrap;
}

/* A table of paths is the one thing on this site that genuinely cannot be made
   narrower — a path is as wide as it is. Scrolling the table alone beats
   scrolling the page sideways, which moves the text out from under the reader. */
.scroll-x {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

pre {
  background: var(--paper-sunk);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 0.75rem 0.9rem;
  overflow-x: auto;
  font-size: 0.85rem;
  line-height: 1.5;
  margin: 0.6rem 0;
}

pre code {
  background: none;
  padding: 0;
  white-space: pre;
}

/* The reference is the one page this column is too narrow for. 44rem suits a
   form and a paragraph, which is what everything else here is; a three-column
   table of HTTP paths in it wraps "POST /api/shares/{id}/complete" onto two
   lines and reads like a mistake. Widening main for everybody would loosen the
   pages that are already right, so it is scoped to the one that needs it —
   and the prose inside keeps its own 38rem measure, because a line of text
   that wide is harder to read, not easier. */
.container.wide {
  max-width: 58rem;
}
