/*
 * thriftapp.is — Kvittunin (C16.1; the first screen is still Nafnspjaldið's).
 *
 * The calling card's first screen, then the page set on the stone — rows of a
 * label at the left and the content at the right, big numbered display lines,
 * a tally — then the band as the page's one teal field, then the record.
 * Teal has two roles — that field, and the stamp (numerals, figures, the launch
 * line, links) — and is never a button or a tint behind text. Hairlines and
 * space do the separating; no sheet, no card, no shadow, no icon. Every colour,
 * radius, font and step of the spacing
 * scale comes from `tokens.css`; there is no hex value in this file and no
 * inline style anywhere on the site (`test/site.test.mjs` asserts both).
 * `DESIGN.md` is the written system, recorded from the shipped site.
 */

/* Inter, self-hosted — latin subset, variable weight. Nothing on this site is
   fetched from a third party, which is what the privacy page is able to say. */
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("/assets/fonts/inter-latin-var.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+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  color-scheme: light;
  -webkit-text-size-adjust: 100%;
  scrollbar-color: var(--border) var(--page);
}

body {
  margin: 0;
  background: var(--page);
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: 17px;
  line-height: 1.62;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* Browser surfaces are part of the design, not the browser's to decide. */
::selection {
  background: var(--accent);
  color: var(--page);
}

body {
  caret-color: var(--accent);
}

::marker {
  color: var(--muted-text);
}

/* Links keep their underline at rest — colour is never the only affordance —
   and the underline thickens and steps toward the word under the pointer. */
a {
  color: var(--ink);
  text-decoration-color: var(--accent);
  text-decoration-thickness: 1px;
  text-underline-offset: 0.28em;
  transition: color 260ms cubic-bezier(0.16, 1, 0.3, 1),
    text-decoration-color 260ms cubic-bezier(0.16, 1, 0.3, 1),
    text-decoration-thickness 260ms cubic-bezier(0.16, 1, 0.3, 1),
    text-underline-offset 260ms cubic-bezier(0.16, 1, 0.3, 1);
}

a:is(:hover, :focus-visible) {
  color: var(--accent);
  text-decoration-color: var(--accent);
  text-decoration-thickness: 2px;
  text-underline-offset: 0.2em;
}

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

.skip-link {
  position: absolute;
  left: -9999px;
}

.skip-link:focus {
  position: static;
  display: inline-block;
  margin: var(--space-md) var(--space-xl);
}

/* ── The wordmark ───────────────────────────────────────────────────────── */

.wordmark {
  display: block;
  height: auto;
}

.wordmark-lg {
  width: clamp(196px, 27vw, 292px);
  margin: 0 auto;
}

/* ── The header ─────────────────────────────────────────────────────────────
   One bar on every page: fixed above the page, the small wordmark as the way
   home at the left, the four-link navigation at the right and the language
   switch after it (C16.3), its content on
   the page column, a hairline under it. On the home page it arrives only once
   the first screen has been scrolled past (below); on every other page it is
   there from the start and the page begins under it. */
.site-header {
  position: fixed;
  inset: 0 0 auto;
  z-index: 2;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-lg) var(--space-2xl);
  /* The bar spans the viewport; its contents sit on the page column's text
     edge — the column's own gutter included — so the wordmark stands over the
     labels below it rather than a gutter's width outside them. */
  padding: var(--space-md) calc(max(0px, (100% - var(--measure)) / 2) + var(--gutter));
  background: var(--page);
}

/* The bar's hairline is its own element so it can draw itself in after the
   bar has landed, left to right, the way the wordmark prints. */
.site-header::after {
  content: "";
  position: absolute;
  inset: auto 0 0;
  height: var(--hairline);
  background: var(--border);
}

.wordmark-sm {
  width: 76px;
}

/* Every page but the home page begins under the bar. */
body:not(.is-home) main {
  padding-top: var(--space-5xl);
}

/* The bar arrives out of a blur and settles; two thirds of the way in it is
   already legible, so the last third is the settle rather than the reveal. */
@keyframes nav-in {
  from {
    opacity: 0;
    visibility: hidden;
    translate: 0 -14px;
    filter: blur(10px);
  }

  65% {
    opacity: 1;
    visibility: visible;
    filter: blur(0);
  }

  to {
    opacity: 1;
    visibility: visible;
    translate: 0 0;
    filter: blur(0);
  }
}

@supports (animation-timeline: scroll()) {
  /* It waits until the first screen's foot lines have gone past, then arrives
     over a third of a viewport of scroll; the hairline follows a beat later. */
  .is-home .site-header {
    animation: nav-in linear both;
    animation-timeline: scroll(root);
    animation-range: 44vh 76vh;
  }

  .is-home .site-header::after {
    animation: ink-on linear both;
    animation-timeline: scroll(root);
    animation-range: 60vh 96vh;
  }
}

.home-link {
  display: inline-block;
  text-decoration: none;
}

.site-nav {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-md) var(--space-xl);
  /* Takes the free space, so the switch after it sits at the right edge and
     the nav stays beside it rather than centring between two neighbours. */
  margin-left: auto;
}

/* Same grammar as the footer links: muted at rest, no underline, and the
   underline arrives with the accent so colour is never the only affordance.
   The current page is set in ink — a position, not a state. */
.site-nav a {
  font-size: 14.5px;
  color: var(--muted-text);
  text-decoration: none;
}

.site-nav a[aria-current="page"] {
  color: var(--ink);
}

.site-nav a:hover,
.site-nav a:focus-visible {
  color: var(--accent);
  text-decoration: underline;
  text-decoration-color: var(--accent);
}

/* The language switch (C16.3): the other language, named in itself, set off
   from the navigation by one hairline — the bar's own rule stood on end — so
   it reads as a different kind of link without a box, a flag or a glyph. The
   nav's grammar otherwise: muted at rest, accent and underline together. On a
   phone the two-letter code stands in for the name (below). */
.lang-switch {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xl);
  font-size: 14.5px;
  color: var(--muted-text);
  text-decoration: none;
}

.lang-switch::before {
  content: "";
  width: var(--border-thin);
  height: 1.1em;
  background: var(--mark-tint);
}

.lang-switch:hover,
.lang-switch:focus-visible {
  color: var(--accent);
}

.lang-switch:hover > span,
.lang-switch:focus-visible > span {
  text-decoration: underline;
  text-decoration-color: var(--accent);
}

.lang-short {
  display: none;
}

/* ── The card face ──────────────────────────────────────────────────────── */

/* The mark holds the middle of the screen and the words sit at its foot: the
   field above them is the composition, not leftover space. Two rows, the mark
   centred in everything the lines do not take. */
.card-face {
  display: grid;
  grid-template-rows: 1fr auto;
  min-height: 100svh;
  padding: var(--space-4xl) var(--gutter) var(--space-4xl);
  text-align: center;
}

.mark-field {
  display: grid;
  place-items: center;
  align-content: center;
}

.foot-lines {
  padding-bottom: var(--space-2xl);
}

/* Size and weight are fixed here on purpose: this line carries the page's one
   plain fact and must not grow into a headline. */
.plain {
  margin: 0 auto;
  max-width: 43ch;
  color: var(--ink-2);
  font-family: var(--font-sans);
  font-size: 19px;
  font-weight: 400;
  line-height: 1.55;
  letter-spacing: normal;
  text-wrap: pretty;
}

/* The launch line is the one live fact on the first screen, so it is the one
   thing there in the accent — a state, in the world's own terms. */
.quiet {
  margin: var(--space-md) 0 0;
  color: var(--accent);
  font-size: 13.5px;
  font-weight: 500;
}

/* ── The authored moment ────────────────────────────────────────────────────
   A calling card is printed, not faded in. The mark wipes on left to right as
   if ink were laid across the card, and the two lines rise once it has landed.
   One sequence, once per load. The wipe is also the hover gesture's ancestor:
   the card settles under the pointer, which is the only interaction the first
   screen has. */

@keyframes ink-on {
  from {
    clip-path: inset(0 100% 0 0);
  }
}

@keyframes lift {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
}

/* The hero mark says the same word as `ink-on`, slowly and out loud — it is the
   page's one authored moment and the only thing on the first screen, so it is
   the one place the site spends real time. Two things differ from every other
   arrival, both deliberate:

     1. Its own curve. The site's `cubic-bezier(0.16, 1, 0.3, 1)` is expo-out:
        three quarters of the travel is over in the first fifth of the duration,
        which is right for something rising into place and wrong for a stroke
        the eye is meant to follow — at 980ms the mark effectively appeared.
        This curve eases in, holds a readable pace across the card, and lands
        soft, so the duration is the gesture rather than a tail on it.
     2. A settle. The mark is drawn at 1.025 and a touch high, and comes to rest
        on the stone as the last of the ink lands, so the stroke ends in a
        position rather than just stopping. Driven on `transform`, which leaves
        the `scale` property free for the hover settle below — two properties,
        no shorthand between them, nothing to overwrite. */
@keyframes print-on {
  from {
    clip-path: inset(0 100% 0 0);
    transform: translateY(10px) scale(1.025);
  }

  70% {
    clip-path: inset(0 0 0 0);
  }

  to {
    clip-path: inset(0 0 0 0);
    transform: none;
  }
}

.wordmark-lg {
  animation: print-on 1150ms cubic-bezier(0.45, 0.05, 0.2, 1) 140ms backwards;
}

/* The lines wait for the mark. The wipe completes at 140ms + 70% of 1150ms, so
   the first line starts just after the ink lands and the second follows it —
   the foot of the card is read after its face, not over it. */
.foot-lines > * {
  animation: lift 760ms cubic-bezier(0.16, 1, 0.3, 1) backwards;
}

.foot-lines > .plain {
  animation-delay: 1000ms;
}

.foot-lines > .quiet {
  animation-delay: 1110ms;
}

/* Hover motion is gated on a pointer that can actually hover, and on the
   visitor not having asked for less of it. */
@media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {
  /* The mark settles under the pointer and comes back when it leaves — the same
     gesture the band's icon makes, so the two read as one language rather than
     as two ideas. A transition, not an animation: nothing to replace, nothing
     to snap, and it reverses correctly when the pointer leaves mid-way. */
  .wordmark-lg {
    transition: scale 520ms cubic-bezier(0.16, 1, 0.3, 1);
  }

  .mark-field:hover .wordmark-lg {
    scale: 0.9965;
  }
}

/* ── The band ───────────────────────────────────────────────────────────────
   The one thing below the first screen: one line, and the mark enlarged and
   tilted past the right edge, so the page carries its own logo as a field
   rather than adding a second sentence. The mark turns as the band enters; the
   note above the rule itself says how, and why it is driven on `rotate:`. */

/* The band is the page's one field of colour: the brand's teal, the line in
   on-dark white, the mark painted one step deeper in the same teal so it reads
   as a field pressed into the field rather than a second colour. */
.band {
  position: relative;
  overflow: hidden;
  background: var(--accent);
}

/* The line's box spans the whole column, so left as-is it would intercept the
   pointer across the mark sitting behind it and the mark could never be
   hovered on its own. The box stops taking pointer events; the words take them
   back, which keeps them selectable. */
.band-line {
  position: relative;
  z-index: 1;
  pointer-events: none;
  transition: translate 620ms cubic-bezier(0.16, 1, 0.3, 1);
}

.band-line {
  max-width: var(--measure);
  margin: 0 auto;
  padding: clamp(72px, 12vw, 148px) var(--gutter);
  font-family: var(--font-display);
  font-size: clamp(26px, 3.6vw, 40px);
  font-weight: 600;
  letter-spacing: -0.03em;
  line-height: 1.12;
  color: var(--on-dark);
}

/* The mark turns as the band passes the viewport: the page says "in
   circulation" with the logo rather than with a sentence.

   Driven on the independent `rotate:` property, never on `transform`. An
   animation replaces the base value of the property it animates, so animating
   `transform` would have taken `translateY(-50%)` with it and dropped the mark
   half a height whenever the timeline failed to resolve. With `rotate:` the
   translate is untouched, and the keyframes start at the same angle the static
   rule sets, so a stalled or unsupported timeline shows the composition rather
   than a broken one. The range ends at `entry 100%` because the page affords
   less scroll than `exit 100%` would need to finish the arc. */

.band-words {
  pointer-events: auto;
}

.band-mark {
  position: absolute;
  top: 50%;
  right: -6%;
  width: min(46vw, 520px);
  aspect-ratio: 1;
  transform: translateY(-50%);
  rotate: -26deg;
  transition: scale 520ms cubic-bezier(0.16, 1, 0.3, 1),
    background-color 620ms cubic-bezier(0.16, 1, 0.3, 1);
  /* The asset is a square PNG whose corners are transparent, and a CSS mask
     does not affect hit testing — the box would still catch the pointer well
     outside the glyph. `clip-path` does affect it, and the mark's silhouette is
     a circle inscribed in its own box, so clipping to that circle makes the
     pointer target the icon rather than the empty air around it. It removes
     nothing visible: the glyph already ends at that circle. Per-pixel alpha
     hit testing would need JavaScript, and this site ships none. */
  clip-path: circle(50%);
  pointer-events: auto;
}

/* The arc never crosses upright. The tilt is the composition — an upright
   circle is the state this mark should never be caught in — so the turn runs
   inside the tilt rather than through it. */
@keyframes turn {
  from {
    rotate: -26deg;
  }
  to {
    rotate: -8deg;
  }
}

@supports (animation-timeline: view()) {
  .band-mark {
    animation: turn linear both;
    animation-timeline: view();
    animation-range: entry 0% entry 100%;
  }
}

/* The paint is guarded by the mask. Without the guard, a browser that cannot
   apply the mask renders a 520px solid square at the band's edge — the one box
   this world does not have. */
@supports ((mask-image: url("")) or (-webkit-mask-image: url(""))) {
  .band-mark {
    background-color: var(--accent-pressed);
    -webkit-mask-image: url("/assets/brand/mark.webp");
    mask-image: url("/assets/brand/mark.webp");
    -webkit-mask-repeat: no-repeat;
    mask-repeat: no-repeat;
    -webkit-mask-size: contain;
    mask-size: contain;
  }
}

/* ── Arrival ────────────────────────────────────────────────────────────────
   The long-form pages were static while the home page printed itself, so a
   visitor who followed a footer link fell off the end of the world. They now
   arrive in the same grammar: the heading prints, the lines under it lift.
   Three steps, on load, no timeline involved. */

.prose > h1 {
  animation: ink-on 880ms cubic-bezier(0.16, 1, 0.3, 1) 60ms backwards;
}

.prose > .updated,
.prose > .notice,
.prose > .lede {
  animation: lift 700ms cubic-bezier(0.16, 1, 0.3, 1) backwards;
}

.prose > .updated {
  animation-delay: 320ms;
}

.prose > .notice {
  animation-delay: 420ms;
}

.prose > .lede {
  animation-delay: 420ms;
}

/* ── Arrival on scroll ──────────────────────────────────────────────────────
   Two moments below the first screen, both inside @supports so that a browser
   without scroll timelines simply shows the content — a reveal that can strand
   its own content is not a reveal, it is a bug. The band's line prints, the
   same gesture the wordmark makes, and the record's rows lift one after
   another, which is a list behaving like a list rather than a section
   reinterpreted as one. */

@supports (animation-timeline: view()) {
  .band-line {
    animation: ink-on linear both;
    animation-timeline: view();
    animation-range: entry 10% entry 70%;
  }

  .record-row {
    animation: lift linear both;
    animation-timeline: view();
  }

  .record-row:nth-child(1) {
    animation-range: entry 8% entry 46%;
  }

  .record-row:nth-child(2) {
    animation-range: entry 14% entry 52%;
  }

  .record-row:nth-child(3) {
    animation-range: entry 20% entry 58%;
  }

  .record-row:nth-child(4) {
    animation-range: entry 26% entry 64%;
  }

  .record-row:nth-child(5) {
    animation-range: entry 32% entry 70%;
  }

  /* The receipt arrives the way the record does: each title prints, each row
     lifts on its own timeline, so a list behaves like a list. */
  .editorial-title,
  .ledger-title {
    animation: ink-on linear both;
    animation-timeline: view();
    animation-range: entry 10% entry 60%;
  }

  .ledger-aside,
  .ledger-body {
    animation: lift linear both;
    animation-timeline: view();
    animation-range: entry 4% entry 36%;
  }

  .big-lines > li,
  .tally > div,
  .tally-title {
    animation: lift linear both;
    animation-timeline: view();
    animation-range: entry 4% entry 36%;
  }
}

/* ── Hover ──────────────────────────────────────────────────────────────────
   Every hover here is a relationship, not a decoration. The band's words move
   the mark behind them; a footer link steps toward its own underline. All of it
   is gated on a pointer that can hover and on the visitor not having asked for
   less motion, and every rule answers :focus-visible too, so a keyboard reaches
   what a mouse reaches. */

@media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {
  .band:hover .band-line,
  .band:focus-within .band-line {
    translate: 8px 0;
  }

  /* The mark answers only to itself, and it answers differently: it settles
     into the field rather than taking the lateral step the words make.
     A transition, never an `animation` — the shorthand would replace this
     element's animation list, dropping the scroll-driven `turn` and snapping
     `rotate` back to its base angle the instant the pointer arrived. `scale:`
     and not `transform:`, because `transform` carries the placement. */
  .band-mark:hover {
    scale: 0.965;
    background-color: var(--accent-deep);
  }

  .footer-links a {
    transition: translate 260ms cubic-bezier(0.16, 1, 0.3, 1);
  }

  .footer-links a:is(:hover, :focus-visible) {
    translate: 3px 0;
  }

  .home-link .wordmark-sm {
    transition: opacity 260ms cubic-bezier(0.16, 1, 0.3, 1);
  }

  .home-link:is(:hover, :focus-visible) .wordmark-sm {
    opacity: 0.62;
  }

  .record-row a {
    transition: color 260ms cubic-bezier(0.16, 1, 0.3, 1);
  }

  /* A step under the pointer comes forward: a short move to the left and a
     step up in size, and its note darkens to be read. On `translate:` and
     `scale:`, so the arrival's `transform` keyframes are left alone. */
  .big-lines > li {
    transition: translate 420ms cubic-bezier(0.16, 1, 0.3, 1),
      scale 420ms cubic-bezier(0.16, 1, 0.3, 1);
  }

  .big-lines > li:hover {
    translate: -6px 0;
    scale: 1.02;
  }

  .big-lines > li:hover .big-note {
    color: var(--ink-2);
  }

  /* The ledger answers the same way: the headline of the row under the
     pointer comes forward, and nothing else in the row moves. */
  .ledger-title {
    transition: translate 420ms cubic-bezier(0.16, 1, 0.3, 1),
      scale 420ms cubic-bezier(0.16, 1, 0.3, 1);
  }

  .ledger-row:hover .ledger-title {
    translate: -6px 0;
    scale: 1.02;
  }
}

@media (prefers-reduced-motion: reduce) {
  .wordmark-lg,
  .foot-lines > *,
  .is-home .site-header,
  .is-home .site-header::after,
  .editorial-title,
  .ledger-title,
  .ledger-aside,
  .ledger-body,
  .ledger-label,
  .statement .w,
  .statement-note,
  .big-lines > li,
  .tally > div,
  .tally-title,
  .band-mark,
  .band-mark:hover,
  .band-line,
  .record-row,
  .prose > h1,
  .prose > .updated,
  .prose > .notice,
  .prose > .lede {
    animation: none;
  }

  a {
    transition: color 160ms ease-out, text-decoration-color 160ms ease-out;
  }
}

/* The 404 is the one page short enough that the footer would float in the middle
   of a tall screen with nothing under it. A column that fills the viewport puts
   it back on the floor; every other page is long enough not to need this, so it
   is scoped rather than applied to `body`. */
.is-error {
  min-height: 100svh;
  display: flex;
  flex-direction: column;
}

.is-error main {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

/* ── The 404s ───────────────────────────────────────────────────────────────
   The split ledger's intro, with the loose thread in the half the emblem
   holds on Um Þrift: the site's one ornament, its teal thread pulled out of
   the weave and hanging. Beside it the page says so in display type, then
   offers the ways on as display links, each on the ledger's hairline. */
.lost {
  width: 100%;
  box-sizing: border-box;
}

.lost-thread .fabric {
  width: 100%;
  margin-top: 0;
}

/* The loose end runs out into the stone the way the fabric's ends do,
   rather than stopping at a cut: the weave's own left-to-right fade,
   intersected with a fade down the last stretch of the hang. Two classes,
   so it wins over `.fabric-left` further down the file. */
.lost-thread .fabric-loose {
  -webkit-mask-image:
    linear-gradient(to right, transparent 0%, black 10%, black 78%, transparent 100%),
    linear-gradient(to bottom, black 80%, transparent 97%);
  -webkit-mask-composite: source-in;
  mask-image:
    linear-gradient(to right, transparent 0%, black 10%, black 78%, transparent 100%),
    linear-gradient(to bottom, black 80%, transparent 97%);
  mask-composite: intersect;
}

.lost-ways {
  margin: var(--space-4xl) 0 0;
  padding: 0;
  list-style: none;
  border-top: var(--hairline) solid var(--border);
}

.lost-ways li {
  border-bottom: var(--hairline) solid var(--border);
}

.lost-ways a {
  display: inline-block;
  padding: var(--space-md) 0;
  font-family: var(--font-display);
  font-size: clamp(22px, 2.4vw, 30px);
  font-weight: 600;
  letter-spacing: -0.025em;
  line-height: 1.15;
  transform-origin: left center;
}

/* ── The editorial grid ────────────────────────────────────────────────────
   Below the first screen the page is set the way a good studio sets a page on
   a stone ground: nothing but space, hairlines and type. Every section is a
   row on the page column — a small label at the left edge, the content in the
   right half — so the left half stays quiet and the type carries the scale.
   Buying and selling are big numbered display lines; the fees are a tally
   tucked into the right column; the figures and numerals take the teal as the
   page's stamp. No sheet, no card, no box. */

@media (prefers-reduced-motion: no-preference) {
  html {
    scroll-behavior: smooth;
  }
}

.editorial {
  max-width: var(--measure);
  margin: 0 auto;
  padding: var(--space-5xl) var(--gutter) 0;
  /* The fixed header must not cover a section a nav link scrolled to. */
  scroll-margin-top: var(--space-5xl);
}

.editorial + .band,
.ledger + .band {
  margin-top: clamp(64px, 10vw, 120px);
}

/* One big centred title for the section that has two rows under it. */
.editorial-title {
  margin: 0 0 var(--space-3xl);
  font-family: var(--font-display);
  font-size: clamp(30px, 4vw, 44px);
  font-weight: 600;
  letter-spacing: -0.03em;
  line-height: 1.08;
  color: var(--ink);
  text-align: center;
  text-wrap: balance;
}

.row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: var(--space-2xl) var(--space-4xl);
  padding: var(--space-4xl) 0;
  border-top: var(--hairline) solid var(--border);
  scroll-margin-top: var(--space-5xl);
}

.row {
  /* The big lines' scale, named once: the label beside them and the numeral
     in front of each take their line box from it (below). */
  --lead-size: clamp(28px, 3.4vw, 40px);
  --lead-line: calc(var(--lead-size) * 1.1);
}

/* The label is the section's name at text size, set in ink: the quiet half of
   the row. An aside under it is where a fact that is not a sentence lives.
   It sits on the first line of the content beside it, never above it. */
.row-label {
  margin: 0;
  font-family: var(--font-sans);
  font-size: 15.5px;
  font-weight: 500;
  color: var(--ink);
}

/* Beside a big list the label shares the first display line's box, so its
   middle is that line's middle — level with the words and with the numeral,
   the way a studio hangs a caption on a headline. */
.row:has(.big-lines) .row-label {
  line-height: var(--lead-line);
}

.row-aside {
  margin: var(--space-sm) 0 0;
  font-size: 14.5px;
  color: var(--muted-text);
  text-wrap: pretty;
}

/* The big list: each step one display line at the scale a headline has, the
   numeral small and teal at its left, an optional quiet note beneath. */
.big-lines {
  list-style: none;
  margin: 0;
  padding: 0;
  counter-reset: step;
}

.big-lines > li {
  display: grid;
  grid-template-columns: 3ch minmax(0, 1fr);
  gap: 0 var(--space-md);
  padding: var(--space-md) 0;
  transform-origin: left center;
}

.big-lines > li:first-child {
  padding-top: 0;
}

/* The numeral takes the lead's line box and centres in it, so it sits on the
   middle of the first display line whatever the line's size. */
.big-lines > li::before {
  counter-increment: step;
  content: counter(step, decimal-leading-zero);
  grid-row: 1 / span 2;
  font-family: var(--font-display);
  font-size: 13px;
  font-weight: 600;
  line-height: var(--lead-line);
  font-variant-numeric: tabular-nums;
  color: var(--accent);
}

.big-lead {
  margin: 0;
  font-family: var(--font-display);
  font-size: var(--lead-size);
  font-weight: 600;
  letter-spacing: -0.03em;
  line-height: var(--lead-line);
  color: var(--ink);
  text-wrap: balance;
}

.big-note {
  grid-column: 2;
  margin: var(--space-xs) 0 0;
  font-size: 14.5px;
  color: var(--muted-text);
  text-wrap: pretty;
  transition: color 420ms cubic-bezier(0.16, 1, 0.3, 1);
}



.tally {
  margin: 0;
}

.tally > div {
  display: flex;
  align-items: baseline;
  gap: var(--space-sm);
  padding: var(--space-md) 0;
  border-top: var(--hairline) solid var(--border);
  font-size: 15.5px;
}

.tally > div:first-child {
  padding-top: 0;
  border-top: none;
}

.tally dt {
  display: flex;
  flex: 1 1 auto;
  align-items: baseline;
  gap: var(--space-sm);
  color: var(--ink-2);
}

/* The leader: a dotted rule that runs from the label to its amount. In the
   muted text tint, not the hairline grey — a hairline reads at 0.5px solid and
   vanishes at 1px dotted on stone. */
.tally dt::after {
  content: "";
  flex: 1 1 auto;
  min-width: var(--space-xl);
  border-bottom: 1px dotted var(--muted-text);
  translate: 0 -0.3em;
}

/* The figures are the receipt's stamp: display face, accent ink. */
.tally dd {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--accent);
  text-align: right;
  white-space: nowrap;
}

/* Where a figure is somebody else's to set, the stamp is a link to it — same
   face and ink as a figure, with the underline every link carries. */
.tally dd a {
  color: inherit;
}

/* Delivery is a second tally under its own small title: what Þrift charges
   above, what the carrier charges below, a gap between them rather than a
   rule, so the two read as one receipt in two parts. */
.tally-title {
  margin: var(--space-4xl) 0 var(--space-md);
  font-family: var(--font-sans);
  font-size: 12.5px;
  font-weight: 500;
  color: var(--muted-text);
}

/* ── The split ledger ───────────────────────────────────────────────────────
   Um Þrift and Aðstoð. A section's name is its headline, set at display size
   down the left half; its text sits in the right half on the headline's
   baseline, the way a ledger's entries share a line. The left half carries
   the page's scale, so the page reads as set rather than as small labels
   beside paragraphs. It opens on one statement in display type, the page's
   name hung on its first line, and the statement's words arrive one after
   another out of the blur the header arrives from on the home page. */

.ledger {
  max-width: var(--measure);
  margin: 0 auto;
  padding: 0 var(--gutter);
}

.ledger-intro {
  --statement-size: clamp(30px, 3.9vw, 46px);
  --statement-line: calc(var(--statement-size) * 1.1);
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: var(--space-2xl) var(--space-4xl);
  align-items: center;
  padding-top: clamp(48px, 8vw, 112px);
  padding-bottom: clamp(64px, 9vw, 128px);
}

/* The page's name is its heading for assistive tech; on screen the nav
   already says where you are, and the emblem holds the left half instead
   (founder, 2026-09-29). */
.ledger-label {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* The emblem stands in the left half, level with the statement's middle. Two
   classes, so the size wins over `.emblem`'s default further down the file. */
.emblem.ledger-emblem {
  --emblem-size: clamp(180px, 24vw, 340px);
}

.statement {
  margin: 0;
  font-family: var(--font-display);
  font-size: var(--statement-size);
  font-weight: 600;
  letter-spacing: -0.03em;
  line-height: var(--statement-line);
  color: var(--ink);
  text-wrap: balance;
  overflow-wrap: anywhere;
}

/* Each word is its own box so it can move; the spaces between stay text. */
.statement .w {
  display: inline-block;
}

/* A link at display size keeps the underline every link has, drawn to scale. */
.statement a {
  text-decoration-thickness: 2px;
  text-underline-offset: 0.14em;
}

.statement a:is(:hover, :focus-visible) {
  text-decoration-thickness: 3px;
  text-underline-offset: 0.1em;
}

.statement-note {
  max-width: 44ch;
  margin: var(--space-3xl) 0 0;
  font-size: 19px;
  line-height: 1.55;
  color: var(--ink-2);
  text-wrap: pretty;
}

.ledger-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: var(--space-lg) var(--space-4xl);
  align-items: first baseline;
  padding: clamp(40px, 5vw, 64px) 0;
  border-top: var(--hairline) solid var(--border);
  scroll-margin-top: var(--space-5xl);
}

.ledger-title {
  margin: 0;
  font-family: var(--font-display);
  font-size: clamp(28px, 3.4vw, 40px);
  font-weight: 600;
  letter-spacing: -0.03em;
  line-height: 1.1;
  color: var(--ink);
  text-wrap: balance;
  transform-origin: left center;
}

/* A question is a sentence, not a name: one step down, so the longest of them
   holds two or three lines in the left half rather than five. */
.ledger-faq .ledger-title {
  font-size: clamp(22px, 2.4vw, 30px);
  letter-spacing: -0.025em;
  line-height: 1.15;
}

.ledger-aside {
  margin: var(--space-lg) 0 0;
  font-size: 15.5px;
  color: var(--muted-text);
}

/* A figure in running text or under a headline is the stamp: display face,
   600, tabular numerals, teal — never a link, so it carries no underline. */
.figure {
  font-family: var(--font-display);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--accent);
}

.ledger-body > p {
  max-width: 46ch;
  margin: 0;
  font-size: 17px;
  line-height: 1.62;
  color: var(--ink-2);
  text-wrap: pretty;
}

/* The arrival. The emblem turns into place while the words come up out of a
   blur one after another, then the note under them lifts. The stagger reads each
   word's place among its siblings; a browser without `sibling-index()`
   drops that one declaration and brings the words in together, which is the
   same arrival without the cadence. */
@keyframes word-in {
  from {
    opacity: 0;
    translate: 0 0.3em;
    filter: blur(8px);
  }
}

/* Behind the motion preference, not left to the reduce block above: these
   rules come later in the file at the same specificity, so they would win
   over its `animation: none` and run for a visitor who asked for less. */
@media (prefers-reduced-motion: no-preference) {
  .statement .w {
    animation: word-in 900ms cubic-bezier(0.16, 1, 0.3, 1) 160ms backwards;
    animation-delay: calc(160ms + sibling-index() * 55ms);
  }

  .statement-note {
    animation: lift 760ms cubic-bezier(0.16, 1, 0.3, 1) 900ms backwards;
  }
}

/* ── The emblem ─────────────────────────────────────────────────────────────
   The mark itself as a solid object: its ring and its þ extruded into depth,
   open where the mark is open — the way a fashion house casts its monogram as
   hardware, not a coin with a picture on it. In CSS 3D, no script: the depth
   is a stack of the mark's own silhouette, one thin layer behind another,
   shading from the teal's deepest step at the front toward ink at the back,
   under a matte face in the brand teal lit faintly from the upper left. Matte, like
   everything else on the stone, and seen through a soft film grain that stays
   where it is while the object turns under it. It stands in the left half of
   Um Þrift and Aðstoð, fades up and turns into place beside the statement,
   and turns to face the pointer wherever it is over it.

   The light does not turn with it: the face's light comes from one registered
   angle that the arrival sweeps and the aim shifts. */

@property --emblem-spin-light {
  syntax: "<angle>";
  inherits: true;
  initial-value: 0deg;
}

/* The aim: 1 while the pointer is over the emblem, and where over it, from
   -1 to 1 across (x) and down (y). Registered so they can ease: the pose and
   the light are both computed from them, so one transition moves both. */
@property --emblem-aim {
  syntax: "<number>";
  inherits: true;
  initial-value: 0;
}

@property --emblem-aim-x {
  syntax: "<number>";
  inherits: true;
  initial-value: 0;
}

@property --emblem-aim-y {
  syntax: "<number>";
  inherits: true;
  initial-value: 0;
}

.emblem {
  --emblem-size: 220px;
  --emblem-depth: calc(var(--emblem-size) * 0.12);
  /* Matte: the face's light is a few percent, not a sheen. */
  --emblem-face-hi: color-mix(in oklab, var(--accent), var(--on-dark) 8%);
  --emblem-face: color-mix(in oklab, var(--accent), var(--on-dark) 3%);
  --emblem-face-lo: var(--accent);
  --emblem-side-front: var(--accent-deep);
  --emblem-side-back: color-mix(in oklab, var(--accent-deep), var(--ink) 70%);
  /* Mask-or-nothing: without a mask the layers would be squares, so the
     emblem is not drawn at all where masks are not supported. */
  display: none;
  position: relative;
  width: var(--emblem-size);
  height: var(--emblem-size);
}

@supports ((mask-image: url("")) or (-webkit-mask-image: url(""))) {
  .emblem {
    display: block;
  }
}

/* A patch of the page's own stone, the emblem's box and a margin round it
   for the turned object to reach into. Isolated, so the grain above blends
   with what is drawn here and nothing else, whatever the page around it does. */
.emblem-stage {
  --emblem-bleed: calc(var(--emblem-size) * 0.12);
  position: absolute;
  inset: calc(var(--emblem-bleed) * -1);
  isolation: isolate;
  background: var(--page);
  pointer-events: none;
}

/* The perspective lives here, one box above the turn. */
.emblem-cast {
  position: absolute;
  inset: var(--emblem-bleed);
  perspective: calc(var(--emblem-size) * 5);
}

/* Film grain, not digital noise: a grey noise tile a little coarser than a
   pixel, at its own low contrast, blended soft-light so it lifts and darkens
   the teal a few percent. It holds still while the object turns under it,
   and it lives the way film grain does: two copies of the tile at two sizes,
   each jumping to a new place every few frames on its own rhythm, so the
   grain never settles into a pattern (after kommakomma.is, which runs the
   same at 3% over its whole site — founder, 2026-09-29). Half and half, then
   at 30%: it moves the teal about 3 levels in 255, half the still grain
   before it, which was too much. On the stone it is under 1, and it fades
   out before the edge of the patch. */
.emblem-grain {
  position: absolute;
  inset: 0;
  background: url("/assets/film-grain.svg") 0 0 / 256px;
  opacity: 0.3;
  mix-blend-mode: soft-light;
  -webkit-mask: radial-gradient(closest-side, var(--ink) 78%, transparent);
  mask: radial-gradient(closest-side, var(--ink) 78%, transparent);
  pointer-events: none;
}

.emblem-grain::before {
  content: "";
  position: absolute;
  inset: 0;
  background: url("/assets/film-grain.svg") 97px -43px / 331px;
  opacity: 0.5;
}

/* Where the grain jumps to. `step-end` holds each place until the next, so it
   cuts rather than slides; the two rhythms (200ms and 280ms) never line up. */
@keyframes emblem-grain-shift {
  0% { background-position: 0 0; }
  10% { background-position: -83px 141px; }
  20% { background-position: 167px -59px; }
  30% { background-position: -211px -173px; }
  40% { background-position: 97px 229px; }
  50% { background-position: 233px 61px; }
  60% { background-position: -139px 197px; }
  70% { background-position: 49px -241px; }
  80% { background-position: -251px 23px; }
  90% { background-position: 181px 157px; }
}

@keyframes emblem-grain-countershift {
  0% { background-position: 97px -43px; }
  12.5% { background-position: -173px 211px; }
  25% { background-position: 263px 89px; }
  37.5% { background-position: -29px -277px; }
  50% { background-position: 151px 173px; }
  62.5% { background-position: -241px -97px; }
  75% { background-position: 19px 283px; }
  87.5% { background-position: 229px -181px; }
}

.emblem-turn,
.emblem-body {
  position: relative;
  display: block;
  width: 100%;
  height: 100%;
  transform-style: preserve-3d;
}

/* Only the aim grid takes the pointer; the stage and the turning layers
   never do, so the hover cannot flicker as the edge of the object moves under
   it, and the emblem is not hovered anywhere the grid cannot say where. */
.emblem-turn {
  pointer-events: none;
}

/* At rest the mark is turned partway and tipped back, so its depth shows
   along the right of the ring and the stem. Under the pointer it turns to
   face it: a little less turned when the pointer is at its middle (-14deg,
   7deg), looking left or right (-44deg to 16deg) and up or down (20deg to
   -6deg) as the pointer goes there, never face-on, so its depth still shows
   wherever it looks. The aim and the place are added, not multiplied, so
   coming in from an edge turns straight toward the pointer rather than a
   little the other way first. The light moves with the turn, not with the
   object. */
.emblem-body {
  --emblem-yaw: calc(var(--emblem-aim) * 14deg + var(--emblem-aim-x) * 30deg);
  --emblem-pitch: calc(var(--emblem-aim) * 3deg + var(--emblem-aim-y) * 13deg);
  --emblem-tilt-light: calc(var(--emblem-yaw) * 1.1);
  transform: rotateY(calc(-28deg + var(--emblem-yaw))) rotateX(calc(10deg - var(--emblem-pitch)));
}

.emblem-layer,
.emblem-face {
  position: absolute;
  inset: 0;
  -webkit-mask: url("/assets/brand/mark.webp") center / contain no-repeat;
  mask: url("/assets/brand/mark.webp") center / contain no-repeat;
}

/* The depth: the silhouette repeated back through the extrusion, each layer a
   step darker than the one in front of it — from the teal's deepest step
   toward ink — so the face ends where the sides begin, with no drawn bevel. */
.emblem-layer {
  background: color-mix(in oklab, var(--emblem-side-front), var(--emblem-side-back) calc(var(--i) * 3.5%));
  transform: translateZ(calc(var(--emblem-depth) * (0.5 - var(--i) / 29)));
}

.emblem-layer:nth-child(1) { --i: 1; }
.emblem-layer:nth-child(2) { --i: 2; }
.emblem-layer:nth-child(3) { --i: 3; }
.emblem-layer:nth-child(4) { --i: 4; }
.emblem-layer:nth-child(5) { --i: 5; }
.emblem-layer:nth-child(6) { --i: 6; }
.emblem-layer:nth-child(7) { --i: 7; }
.emblem-layer:nth-child(8) { --i: 8; }
.emblem-layer:nth-child(9) { --i: 9; }
.emblem-layer:nth-child(10) { --i: 10; }
.emblem-layer:nth-child(11) { --i: 11; }
.emblem-layer:nth-child(12) { --i: 12; }
.emblem-layer:nth-child(13) { --i: 13; }
.emblem-layer:nth-child(14) { --i: 14; }
.emblem-layer:nth-child(15) { --i: 15; }
.emblem-layer:nth-child(16) { --i: 16; }
.emblem-layer:nth-child(17) { --i: 17; }
.emblem-layer:nth-child(18) { --i: 18; }
.emblem-layer:nth-child(19) { --i: 19; }
.emblem-layer:nth-child(20) { --i: 20; }
.emblem-layer:nth-child(21) { --i: 21; }
.emblem-layer:nth-child(22) { --i: 22; }
.emblem-layer:nth-child(23) { --i: 23; }
.emblem-layer:nth-child(24) { --i: 24; }
.emblem-layer:nth-child(25) { --i: 25; }
.emblem-layer:nth-child(26) { --i: 26; }
.emblem-layer:nth-child(27) { --i: 27; }
.emblem-layer:nth-child(28) { --i: 28; }

.emblem-face {
  background: linear-gradient(
    calc(150deg + var(--emblem-spin-light) + var(--emblem-tilt-light)),
    var(--emblem-face-hi) 0%,
    var(--emblem-face) 46%,
    var(--emblem-face-lo) 100%
  );
  backface-visibility: hidden;
  transform: translateZ(calc(var(--emblem-depth) / 2));
}

.emblem-back {
  transform: rotateY(180deg) translateZ(calc(var(--emblem-depth) / 2));
}

/* The aim grid: thirteen columns of thirteen cells over the emblem, fine
   enough that the steps between cells blur into one glide (seven was coarse
   enough to see each step), a little wider than it so the turn starts as the
   pointer arrives. Empty, and laid out only
   where there is a pointer to aim with. */
.emblem-aim {
  position: absolute;
  inset: -8%;
  z-index: 1;
  display: none;
}

.emblem-aim > span {
  display: flex;
  flex: 1;
  flex-direction: column;
}

.emblem-aim > span > span {
  flex: 1;
}

/* The emblem's motion, all of it behind the motion preference. It is not
   there for half a second, then it turns a half turn and more into place
   while it fades in out of a slight blur, the light sweeping across its face
   as it lands. The turn sets off with the fade; its first instant is its
   fastest, so the first frame that can be seen is already moving: it is
   never seen standing still, the fade covers the turn's sudden start, and
   the whole half turn happens inside the fade (founder, 2026-09-29). The wait
   also gives the mask time to arrive. Each gesture on its own box — the fade
   on `.emblem`, the turn on `.emblem-turn`, the aim on `.emblem-body` — so
   none replaces another's `transform`. */
@keyframes emblem-fade {
  from {
    opacity: 0;
    filter: blur(6px);
    scale: 0.94;
  }
}

@keyframes emblem-in {
  from {
    transform: rotateY(-200deg);
    --emblem-spin-light: -150deg;
  }
}

@media (prefers-reduced-motion: no-preference) {
  .ledger-emblem {
    animation: emblem-fade 650ms cubic-bezier(0.25, 0.46, 0.45, 0.94) 500ms backwards;
  }

  .ledger-emblem .emblem-turn {
    animation: emblem-in 1700ms cubic-bezier(0.16, 1, 0.3, 1) 500ms backwards;
  }

  .emblem-grain {
    animation: emblem-grain-shift 200ms step-end infinite;
  }

  .emblem-grain::before {
    animation: emblem-grain-countershift 280ms step-end infinite;
  }
}

/* The pointer: over the emblem the aim eases to 1, and the column and the
   cell under the pointer set where it looks. Moving across the grid retargets
   the ease from wherever it is, so the emblem follows the pointer with a
   little weight rather than stepping. When the pointer leaves, it sets off
   at once and eases back to rest over a second and a half, neither snapping
   nor sticking (founder, 2026-09-29).
   The transition on `.emblem` is the way back; the one under `:hover` is the
   way in and across. A browser without `:has()` still turns it toward the
   middle. */
@media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {
  .emblem {
    transition:
      --emblem-aim 1500ms cubic-bezier(0.25, 0.46, 0.45, 0.94),
      --emblem-aim-x 1500ms cubic-bezier(0.25, 0.46, 0.45, 0.94),
      --emblem-aim-y 1500ms cubic-bezier(0.25, 0.46, 0.45, 0.94);
  }

  .emblem-aim {
    display: flex;
  }

  .emblem:hover {
    --emblem-aim: 1;
    transition:
      --emblem-aim 1000ms cubic-bezier(0.33, 1, 0.68, 1),
      --emblem-aim-x 1200ms cubic-bezier(0.33, 1, 0.68, 1),
      --emblem-aim-y 1200ms cubic-bezier(0.33, 1, 0.68, 1);
  }

  .emblem:has(> .emblem-aim > :nth-child(1):hover) { --emblem-aim-x: -1; }
  .emblem:has(> .emblem-aim > :nth-child(2):hover) { --emblem-aim-x: -0.833; }
  .emblem:has(> .emblem-aim > :nth-child(3):hover) { --emblem-aim-x: -0.667; }
  .emblem:has(> .emblem-aim > :nth-child(4):hover) { --emblem-aim-x: -0.5; }
  .emblem:has(> .emblem-aim > :nth-child(5):hover) { --emblem-aim-x: -0.333; }
  .emblem:has(> .emblem-aim > :nth-child(6):hover) { --emblem-aim-x: -0.167; }
  .emblem:has(> .emblem-aim > :nth-child(8):hover) { --emblem-aim-x: 0.167; }
  .emblem:has(> .emblem-aim > :nth-child(9):hover) { --emblem-aim-x: 0.333; }
  .emblem:has(> .emblem-aim > :nth-child(10):hover) { --emblem-aim-x: 0.5; }
  .emblem:has(> .emblem-aim > :nth-child(11):hover) { --emblem-aim-x: 0.667; }
  .emblem:has(> .emblem-aim > :nth-child(12):hover) { --emblem-aim-x: 0.833; }
  .emblem:has(> .emblem-aim > :nth-child(13):hover) { --emblem-aim-x: 1; }

  .emblem:has(> .emblem-aim > * > :nth-child(1):hover) { --emblem-aim-y: -1; }
  .emblem:has(> .emblem-aim > * > :nth-child(2):hover) { --emblem-aim-y: -0.833; }
  .emblem:has(> .emblem-aim > * > :nth-child(3):hover) { --emblem-aim-y: -0.667; }
  .emblem:has(> .emblem-aim > * > :nth-child(4):hover) { --emblem-aim-y: -0.5; }
  .emblem:has(> .emblem-aim > * > :nth-child(5):hover) { --emblem-aim-y: -0.333; }
  .emblem:has(> .emblem-aim > * > :nth-child(6):hover) { --emblem-aim-y: -0.167; }
  .emblem:has(> .emblem-aim > * > :nth-child(8):hover) { --emblem-aim-y: 0.167; }
  .emblem:has(> .emblem-aim > * > :nth-child(9):hover) { --emblem-aim-y: 0.333; }
  .emblem:has(> .emblem-aim > * > :nth-child(10):hover) { --emblem-aim-y: 0.5; }
  .emblem:has(> .emblem-aim > * > :nth-child(11):hover) { --emblem-aim-y: 0.667; }
  .emblem:has(> .emblem-aim > * > :nth-child(12):hover) { --emblem-aim-y: 0.833; }
  .emblem:has(> .emblem-aim > * > :nth-child(13):hover) { --emblem-aim-y: 1; }
}

/* ── Fabric ─────────────────────────────────────────────────────────────────
   Under Að kaupa and Að selja, in the half the big lists leave empty: fine
   lines that fall like cloth from a pin — gathered at one point, opening and
   folding away from it — one of them the teal thread. Both ends fade into the
   stone rather than stopping at a cut. The lines draw themselves outward from
   the gather as the row comes up. Texture, not a picture. */

.fabric {
  display: block;
  width: calc(100% - var(--space-4xl));
  height: auto;
  margin-top: var(--space-3xl);
  overflow: visible;
}

/* The fade toward each end is the cloth running out of the frame; the gather
   end fades shorter, so the pin reads as a point the lines come from. */
.fabric-left {
  -webkit-mask-image: linear-gradient(to right, transparent 0%, black 10%, black 78%, transparent 100%);
  mask-image: linear-gradient(to right, transparent 0%, black 10%, black 78%, transparent 100%);
}

.fabric-right {
  -webkit-mask-image: linear-gradient(to left, transparent 0%, black 10%, black 78%, transparent 100%);
  mask-image: linear-gradient(to left, transparent 0%, black 10%, black 78%, transparent 100%);
}

.fabric-line {
  fill: none;
  stroke: var(--mark-tint);
  stroke-width: 1;
  stroke-linecap: round;
}

.fabric-thread {
  stroke: var(--accent);
  stroke-width: 1.25;
}

@keyframes fabric-draw {
  from {
    stroke-dashoffset: 1;
  }
}

@media (prefers-reduced-motion: no-preference) {
  @supports (animation-timeline: view()) {
    .fabric {
      view-timeline-name: --fabric;
    }

    .fabric-line {
      stroke-dasharray: 1;
      animation: fabric-draw linear both;
      animation-timeline: --fabric;
    }

    .fabric-line:nth-child(1) { animation-range: entry 0% cover 40%; }
    .fabric-line:nth-child(2) { animation-range: entry 6% cover 43%; }
    .fabric-line:nth-child(3) { animation-range: entry 12% cover 46%; }
    .fabric-line:nth-child(4) { animation-range: entry 18% cover 49%; }
    .fabric-line:nth-child(5) { animation-range: entry 24% cover 52%; }
    .fabric-line:nth-child(6) { animation-range: entry 30% cover 55%; }
    .fabric-line:nth-child(7) { animation-range: entry 36% cover 58%; }
    .fabric-line:nth-child(8) { animation-range: entry 42% cover 61%; }
  }
}

/* The 404s' thread draws itself on load rather than on scroll — the page is
   one screen — the weave first, line after line, then the loose thread, which
   takes longest because most of its length is the fall. The shorthand resets
   the scroll timeline the fabric above runs on. After the arrival the ways on
   lift one after another, a list behaving like a list. */
@media (prefers-reduced-motion: no-preference) {
  .fabric-loose .fabric-line {
    stroke-dasharray: 1;
    /* The base delay is in the shorthand, so a browser without
       `sibling-index()` keeps the order (weave, thread, then the links) and
       only loses the cadence. */
    animation: fabric-draw 1500ms cubic-bezier(0.45, 0.05, 0.2, 1) 180ms backwards;
    animation-delay: calc(180ms + sibling-index() * 70ms);
  }

  .fabric-loose .fabric-thread {
    animation-duration: 2600ms;
    animation-delay: 520ms;
  }

  .lost-ways li {
    animation: lift 700ms cubic-bezier(0.16, 1, 0.3, 1) 1000ms backwards;
    animation-delay: calc(1000ms + sibling-index() * 70ms);
  }
}

@media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {
  .lost-ways a {
    transition: translate 420ms cubic-bezier(0.16, 1, 0.3, 1),
      scale 420ms cubic-bezier(0.16, 1, 0.3, 1);
  }

  .lost-ways a:is(:hover, :focus-visible) {
    translate: -6px 0;
    scale: 1.02;
  }
}

/* ── The company record ─────────────────────────────────────────────────── */

/* The record and the footer draw their rules on the page column's text
   width, not across its gutters, so every hairline on a page starts and ends
   where the rows' hairlines do. */
.record {
  width: min(100% - 2 * var(--gutter), var(--measure) - 2 * var(--gutter));
  margin: 0 auto;
  padding: var(--space-4xl) 0;
  border-top: var(--hairline) solid var(--border);
}

.is-home .record {
  padding-top: var(--space-3xl);
}

/* Five rows since the kennitala joined the record (C16.1): legal name, address,
   email, phone, kennitala, one column each. */
.record-list {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 0;
  margin: 0;
}

.record-row {
  padding-left: var(--space-xl);
  border-left: var(--hairline) solid var(--border);
}

.record-row:first-child {
  padding-left: 0;
  border-left: none;
}

.record-row dt {
  font-size: 12.5px;
  color: var(--muted-text);
  margin-bottom: var(--space-xs);
}

.record-row dd {
  margin: 0;
  font-size: 15.5px;
  font-weight: 500;
  color: var(--ink);
  overflow-wrap: anywhere;
}

/* A value nobody has decided yet must not carry the authority of one that is
   settled — this record is the page's proof that a real company exists. */
.record-row dd.is-pending {
  font-weight: 400;
  color: var(--muted-text);
}

/* ── Long-form pages ────────────────────────────────────────────────────── */

.prose {
  max-width: var(--measure-text);
  margin: 0 auto;
  padding: var(--space-4xl) var(--gutter) var(--space-5xl);
}

.prose h1 {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(30px, 5vw, 44px);
  letter-spacing: -0.035em;
  line-height: 1.08;
  text-wrap: balance;
  margin: 0;
}

.prose h2 {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 20px;
  letter-spacing: -0.02em;
  color: var(--ink);
  margin: var(--space-4xl) 0 var(--space-md);
}

.prose h3 {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 16px;
  letter-spacing: -0.01em;
  margin: var(--space-3xl) 0 var(--space-sm);
}

.prose p,
.prose li {
  color: var(--ink-2);
  font-size: 16.5px;
  text-wrap: pretty;
}

.prose ul {
  padding-left: var(--space-xl);
  margin: var(--space-lg) 0;
}

.prose li {
  margin-bottom: var(--space-md);
}

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

.lede {
  font-size: 19px;
  color: var(--ink);
  line-height: 1.55;
  margin: var(--space-2xl) 0 0;
}

.updated {
  margin: var(--space-md) 0 0;
  font-size: 13px;
  color: var(--muted-text);
}

.notice {
  margin: var(--space-2xl) 0 0;
  padding: var(--space-lg) var(--space-xl);
  background: var(--tan-bg);
  border-radius: var(--radius-md);
}

.notice p {
  margin: 0;
  color: var(--tan-text);
  font-size: 14.5px;
}

/* ── Footer ─────────────────────────────────────────────────────────────── */

.site-footer {
  width: min(100% - 2 * var(--gutter), var(--measure) - 2 * var(--gutter));
  margin: 0 auto;
  padding: var(--space-2xl) 0 var(--space-4xl);
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-md) var(--space-2xl);
  border-top: var(--hairline) solid var(--border);
}

.footer-links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-lg) var(--space-2xl);
}

.footer-links a,
.footer-legal {
  font-size: 13.5px;
  color: var(--muted-text);
}

.footer-links a {
  text-decoration: none;
}

/* Colour alone is never the affordance: the underline arrives with it. */
.footer-links a:hover,
.footer-links a:focus-visible {
  color: var(--accent);
  text-decoration: underline;
  text-decoration-color: var(--accent);
}

.footer-legal {
  margin: 0;
}


/* ── Phone ──────────────────────────────────────────────────────────────── */

@media (max-width: 720px) {
  body {
    font-size: 16px;
  }

  .card-face {
    padding-top: var(--space-3xl);
  }

  .editorial {
    padding-top: var(--space-4xl);
  }

  .row {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-lg);
    padding: var(--space-3xl) 0;
  }

  /* Stacked above the list, the label has no line beside it to sit on. */
  .row:has(.big-lines) .row-label {
    line-height: inherit;
  }

  /* Stacked, the emblem opens the page above the statement, smaller, and
     its grain finer with it, so the grain keeps its size against the object. */
  .emblem.ledger-emblem {
    --emblem-size: 104px;
  }

  .ledger-emblem .emblem-grain {
    background-size: 160px;
  }

  .ledger-emblem .emblem-grain::before {
    background-size: 207px;
  }

  .ledger-intro {
    justify-items: start;
  }

  /* Stacked, the label sits straight above its list; there is no empty half
     for the fabric to fill. */
  .fabric {
    display: none;
  }

  .ledger-intro,
  .ledger-row {
    grid-template-columns: minmax(0, 1fr);
  }

  .ledger-intro {
    padding-top: var(--space-3xl);
    padding-bottom: var(--space-4xl);
  }

  .ledger-row {
    align-items: start;
    padding: var(--space-3xl) 0;
  }

  /* On a phone the bar keeps the wordmark as the way home, smaller, and
     drops the home link — Forsíða / Home, which says the same thing — so the
     bar stays one line. The link stays in the markup for every other width. */
  .wordmark-sm {
    width: 48px;
  }

  .site-nav a:first-child {
    display: none;
  }

  /* The wordmark, three links and the switch hold one line down to a 360px
     screen (C16.3; measured, the Icelandic bar is the longer one at 313px of
     the 320 a 360px phone leaves inside its gutters). It wraps at 320px. */
  .site-header {
    column-gap: var(--space-md);
    padding-top: var(--space-lg);
    padding-bottom: var(--space-lg);
  }

  .site-nav {
    column-gap: var(--space-md);
  }

  .site-nav a {
    font-size: 13px;
  }

  /* The switch shows its two-letter code on a phone, in the display face, so
     it reads as a different kind of link without the hairline the bar has no
     room for. The name stays in the link, hidden only from sight, so
     assistive tech still says "English" or "Íslenska". */
  .lang-switch {
    font-family: var(--font-display);
    font-size: 13px;
    font-weight: 600;
    letter-spacing: 0.04em;
  }

  .lang-switch::before {
    display: none;
  }

  /* Two letters are a small thing to hit: the padding makes the target at
     least 24px each way (WCAG 2.5.8), and the matching negative margin keeps
     it out of the bar's measure. */
  .lang-switch {
    padding: var(--space-md) var(--space-sm);
    margin: calc(-1 * var(--space-md)) calc(-1 * var(--space-sm));
  }

  .lang-name {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }

  .lang-short {
    display: inline;
  }

  /* The thread stays on a phone, above the statement: it is the page. */
  .lost-thread .fabric {
    display: block;
    width: min(100%, 300px);
  }

  .record-list {
    grid-template-columns: minmax(0, 1fr);
  }

  .record-row {
    padding: var(--space-lg) 0 0;
    margin-top: var(--space-lg);
    border-left: none;
    border-top: var(--hairline) solid var(--border);
  }

  .record-row:first-child {
    margin-top: 0;
    padding-top: 0;
    border-top: none;
  }

  .band-mark {
    width: 62vw;
    right: -20%;
  }

  .site-footer {
    padding-bottom: var(--space-3xl);
  }
}
