/* ===================================================================
   Unbind — a bindery for PDFs
   Palette is drawn from library binding: buckram cloth, ink, gilt
   stamping and uncoated paper. The stitch is the structural motif.
   =================================================================== */

:root {
  /* colour */
  --ink:        #16191f;
  --ink-soft:   #3b414a;
  --muted:      #6d736f;
  --paper:      #f2f3ef;
  --paper-deep: #e8eae4;
  --sheet:      #ffffff;
  --cloth:      #1d4d4f;
  --cloth-lift: #2a6b6d;
  --cloth-wash: #e5eded;
  --foil:       #a8792a;
  --rule:       #d9dcd4;
  --alarm:      #9c3226;

  /* type — Fraunces carries the personality, Inter stays out of its way */
  --display: "Fraunces", Georgia, "Times New Roman", serif;
  --body:    "Inter", system-ui, -apple-system, sans-serif;
  --mono:    "JetBrains Mono", ui-monospace, "SF Mono", Menlo, monospace;

  /* measure */
  --gutter: clamp(1.25rem, 4vw, 4.5rem);
  --page:   72rem;
  --radius: 10px;

  --ease: cubic-bezier(.2, .7, .3, 1);
}

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

/* The [hidden] attribute only carries `display: none` at user-agent
   specificity, so any class here that sets display — .btn, .result, .field —
   silently overrides it and the element stays on screen. This puts the
   attribute back in charge wherever it is used. */
[hidden] { display: none !important; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--body);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  /* A faint fibre in the paper, so the flat areas are not dead flat. */
  background-image:
    radial-gradient(circle at 20% 15%, rgba(29, 77, 79, .045), transparent 45%),
    radial-gradient(circle at 85% 5%, rgba(168, 121, 42, .05), transparent 40%);
  background-attachment: fixed;
}

/* A serif needs looser tracking and more leading than the grotesque did.
   opsz is left on auto so Fraunces adjusts contrast to the size it is set at. */
h1, h2, h3 {
  font-family: var(--display);
  font-weight: 600;
  line-height: 1.15;
  letter-spacing: -.01em;
  font-optical-sizing: auto;
  margin: 0;
  text-wrap: balance;
}

p { margin: 0; }

a { color: var(--cloth); text-decoration-thickness: 1px; text-underline-offset: 3px; }

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

.skip {
  position: absolute;
  left: -9999px;
  top: .5rem;
  background: var(--ink);
  color: var(--paper);
  padding: .6rem 1rem;
  border-radius: 6px;
  z-index: 50;
}
.skip:focus { left: .75rem; }

.eyebrow {
  font-family: var(--mono);
  font-size: .72rem;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--cloth);
  margin-bottom: 1.1rem;
}

/* ------------------------------------------------------------ masthead */

.masthead {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  max-width: var(--page);
  margin: 0 auto;
  padding: 1.4rem var(--gutter);
}

.wordmark {
  display: inline-flex;
  align-items: center;
  gap: .6rem;
  text-decoration: none;
  color: var(--ink);
}

/* Three stitch holes, echoing the binding edge in the hero. */
.wordmark__stitch {
  display: inline-flex;
  flex-direction: column;
  gap: 3px;
  padding: 6px 5px;
  background: var(--cloth);
  border-radius: 5px;
}
.wordmark__stitch i {
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: var(--paper);
}

.wordmark__name {
  font-family: var(--display);
  font-weight: 700;
  font-size: 1.3rem;
  letter-spacing: -.012em;
  font-variation-settings: "opsz" 32, "SOFT" 20, "WONK" 1;
}

.masthead__nav {
  display: flex;
  gap: 1.6rem;
  font-size: .93rem;
}
.masthead__nav a {
  color: var(--ink-soft);
  text-decoration: none;
  padding-bottom: 2px;
  border-bottom: 1px solid transparent;
  transition: border-color .2s var(--ease), color .2s var(--ease);
}
.masthead__nav a:hover { color: var(--ink); border-color: var(--cloth); }

/* ---------------------------------------------------------------- hero */

.hero {
  max-width: var(--page);
  margin: 0 auto;
  padding: clamp(2rem, 6vw, 5rem) var(--gutter) clamp(3rem, 7vw, 5.5rem);
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, .95fr);
  gap: clamp(2rem, 5vw, 4rem);
  align-items: center;
}

/* The one place the display face is turned all the way up: large optical size
   for crisp thin strokes, SOFT to round the terminals, WONK for Fraunces'
   alternate g and italic-leaning forms. */
.hero__title {
  font-size: clamp(2.3rem, 5.8vw, 4rem);
  font-weight: 600;
  font-variation-settings: "opsz" 120, "SOFT" 28, "WONK" 1;
  line-height: 1.02;
  letter-spacing: -.018em;
  margin-bottom: 1.4rem;
}

.hero__lede {
  max-width: 44ch;
  color: var(--ink-soft);
  font-size: clamp(1rem, 1.6vw, 1.09rem);
}

.hero__actions { margin-top: 2rem; }

.hero__formats {
  font-family: var(--mono);
  font-size: .74rem;
  letter-spacing: .05em;
  color: var(--muted);
  margin-top: .95rem;
}

/* ------------------------------------------- the gathering / drop zone */

.hero__stack { display: flex; justify-content: center; }

.dropzone {
  --fan: 1;
  width: 100%;
  max-width: 26rem;
  padding: 2.5rem 1.5rem 1.75rem;
  border: 1.5px dashed var(--rule);
  border-radius: 18px;
  background: rgba(255, 255, 255, .5);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.6rem;
  cursor: pointer;
  transition: border-color .25s var(--ease), background .25s var(--ease), transform .25s var(--ease);
}
.dropzone:hover,
.dropzone:focus-visible { border-color: var(--cloth); background: rgba(255, 255, 255, .78); }
.dropzone.is-over {
  --fan: 2.1;
  border-color: var(--cloth);
  border-style: solid;
  background: var(--cloth-wash);
  transform: scale(1.012);
}

.gathering {
  position: relative;
  width: 11.5rem;
  height: 13.5rem;
}

.sheet {
  position: absolute;
  inset: 0;
  background: var(--sheet);
  border: 1px solid var(--rule);
  border-radius: 2px 8px 8px 2px;
  transform-origin: 0% 50%;
  box-shadow: 0 8px 22px -14px rgba(22, 25, 31, .5);
  transition: transform .45s var(--ease);
}
/* Each leaf lifts a little further than the one beneath it. */
.sheet--1 { z-index: 4; transform: rotate(0deg); }
.sheet--2 { z-index: 3; transform: rotate(calc(2.4deg * var(--fan)))  translateX(2px); background: #fcfcfa; }
.sheet--3 { z-index: 2; transform: rotate(calc(4.8deg * var(--fan)))  translateX(4px); background: #f8f9f5; }
.sheet--4 { z-index: 1; transform: rotate(calc(7.4deg * var(--fan)))  translateX(6px); background: #f3f4f0; }

/* Ruled lines on the face of the top leaf. */
.sheet--1 { padding: 2.6rem 1.25rem 0 2.1rem; display: flex; flex-direction: column; gap: .62rem; }
.sheet__rule {
  height: 5px;
  border-radius: 3px;
  background: var(--paper-deep);
}
.sheet__rule:first-child { background: var(--cloth); opacity: .8; width: 62%; height: 7px; }
.sheet__rule--short { width: 45%; }

/* The sewn edge: five holes and the thread that runs through them. */
.binding {
  position: absolute;
  z-index: 5;
  left: .62rem;
  top: 1.15rem;
  bottom: 1.15rem;
  width: 6px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  align-items: center;
}
.binding::before {
  content: "";
  position: absolute;
  inset: 4px auto 4px 50%;
  width: 0;
  border-left: 1.5px dashed var(--cloth);
  opacity: .55;
  transform: translateX(-50%);
}
.binding i {
  position: relative;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--cloth);
  box-shadow: 0 0 0 2px var(--sheet);
}

.dropzone__label { text-align: center; line-height: 1.4; }
.dropzone__label strong {
  display: block;
  font-family: var(--display);
  font-weight: 600;
  font-size: 1.1rem;
  letter-spacing: -.003em;
}
.dropzone__label span { font-size: .87rem; color: var(--muted); }

/* On first paint the gathering fans open — the site's one orchestrated move. */
@media (prefers-reduced-motion: no-preference) {
  .gathering .sheet { animation: fan .9s var(--ease) backwards; }
  .sheet--2 { animation-delay: .06s; }
  .sheet--3 { animation-delay: .12s; }
  .sheet--4 { animation-delay: .18s; }
  @keyframes fan {
    from { transform: rotate(0deg) translateX(0); opacity: 0; }
  }
}

/* ----------------------------------------------------------- buttons */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .5rem;
  font-family: var(--body);
  font-size: .94rem;
  font-weight: 600;
  letter-spacing: -.005em;
  padding: .72rem 1.35rem;
  border-radius: 8px;
  border: 1px solid transparent;
  cursor: pointer;
  text-decoration: none;
  white-space: nowrap;
  transition: background .18s var(--ease), color .18s var(--ease),
              border-color .18s var(--ease), transform .12s var(--ease);
}
.btn:active { transform: translateY(1px); }
.btn:disabled { opacity: .45; cursor: not-allowed; transform: none; }

.btn--primary { background: var(--cloth); color: #fff; }
.btn--primary:hover:not(:disabled) { background: var(--cloth-lift); }

.btn--ghost { background: transparent; color: var(--ink-soft); border-color: var(--rule); }
.btn--ghost:hover:not(:disabled) { border-color: var(--cloth); color: var(--cloth); }

/* Gilt stamping, kept for the one moment that earns it: the finished file. */
.btn--foil {
  background: linear-gradient(180deg, #c79a45, var(--foil));
  color: #fff;
  box-shadow: 0 6px 18px -10px rgba(168, 121, 42, .9);
}
.btn--foil:hover { filter: brightness(1.06); }

.btn--sm { padding: .45rem .85rem; font-size: .84rem; }
.btn--lg { padding: .88rem 1.9rem; font-size: 1rem; }

/* -------------------------------------------------------- workbench */

.workbench {
  position: relative;
  max-width: var(--page);
  margin: 0 auto;
  padding: 0 var(--gutter) clamp(3rem, 7vw, 5rem);
}

/* The thread: a single stitched line binding every panel together. */
.thread {
  position: absolute;
  left: var(--gutter);
  top: .5rem;
  bottom: clamp(3rem, 7vw, 5rem);
  width: 0;
  border-left: 1.5px dashed var(--rule);
}

.panel {
  position: relative;
  padding-left: clamp(1.5rem, 3vw, 2.6rem);
  margin-bottom: 2.6rem;
}

.panel__head {
  display: flex;
  align-items: center;
  gap: .8rem;
  margin-bottom: 1.15rem;
}
.panel__head h2 {
  font-size: 1.12rem;
  font-weight: 600;
  letter-spacing: -.01em;
}

/* A knot where the thread meets each panel. The negative margin pulls it back
   out of the panel's own left padding so it sits centred on the thread. */
.knot {
  flex: none;
  width: 11px;
  height: 11px;
  border-radius: 50%;
  background: var(--paper);
  border: 2.5px solid var(--cloth);
  margin-left: calc(-1 * clamp(1.5rem, 3vw, 2.6rem) - 4.75px);
  margin-right: calc(clamp(1.5rem, 3vw, 2.6rem) - 11px);
}

.tally {
  font-family: var(--mono);
  font-size: .76rem;
  color: var(--muted);
  letter-spacing: .04em;
}
.panel__head .btn { margin-left: auto; }

.panel__hint {
  font-size: .84rem;
  color: var(--muted);
  margin: .75rem 0 1rem;
}

/* --------------------------------------------------------- file list */

.filelist {
  list-style: none;
  margin: 0 0 1rem;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: .5rem;
}

.fileitem {
  display: flex;
  align-items: center;
  gap: .9rem;
  padding: .75rem .9rem;
  background: var(--sheet);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  transition: border-color .2s var(--ease), box-shadow .2s var(--ease);
}
.fileitem:hover { border-color: #c6cabf; }
.fileitem.is-dragging { opacity: .4; }
.fileitem.is-drop-target { border-color: var(--cloth); box-shadow: 0 0 0 3px var(--cloth-wash); }

.fileitem__grip {
  cursor: grab;
  color: var(--muted);
  line-height: 0;
  flex: none;
  display: none;
}
.filelist.is-sortable .fileitem__grip { display: block; }

.fileitem__body { min-width: 0; flex: 1; }
.fileitem__name {
  font-weight: 500;
  font-size: .94rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.fileitem__meta {
  font-family: var(--mono);
  font-size: .73rem;
  color: var(--muted);
  letter-spacing: .03em;
  margin-top: .18rem;
}
.fileitem__meta .locked { color: var(--foil); }

.fileitem__remove {
  flex: none;
  background: none;
  border: 0;
  color: var(--muted);
  cursor: pointer;
  padding: .3rem;
  line-height: 0;
  border-radius: 5px;
}
.fileitem__remove:hover { color: var(--alarm); background: rgba(156, 50, 38, .08); }

/* ------------------------------------------------------------- tools */

/* Eleven tools is too many to read as one list, so they split by what they
   act on. The rule runs to the right of the label to bind the group together. */
.group {
  display: flex;
  align-items: center;
  gap: .8rem;
  font-family: var(--mono);
  font-size: .7rem;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0 0 .7rem;
}
.group::after {
  content: "";
  flex: 1;
  height: 0;
  border-top: 1px dashed var(--rule);
}
.group + .tools { margin-bottom: 1.9rem; }

.tools {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(15.5rem, 1fr));
  gap: .75rem;
}

.tool {
  display: grid;
  grid-template-columns: auto 1fr;
  grid-template-areas: "mark name" "mark desc";
  column-gap: .85rem;
  row-gap: .18rem;
  text-align: left;
  padding: 1.05rem 1.1rem;
  background: var(--sheet);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  cursor: pointer;
  font-family: inherit;
  color: inherit;
  transition: border-color .18s var(--ease), background .18s var(--ease),
              box-shadow .18s var(--ease), transform .18s var(--ease);
}
.tool:hover { border-color: var(--cloth-lift); transform: translateY(-1px); }
.tool[aria-checked="true"] {
  border-color: var(--cloth);
  background: var(--cloth-wash);
  box-shadow: 0 0 0 1px var(--cloth);
}
.tool[disabled] { opacity: .4; cursor: not-allowed; transform: none; }

.tool__mark {
  grid-area: mark;
  align-self: start;
  width: 2.1rem;
  height: 2.1rem;
  display: grid;
  place-items: center;
  border-radius: 7px;
  background: var(--paper);
  color: var(--cloth);
  flex: none;
}
.tool[aria-checked="true"] .tool__mark { background: var(--cloth); color: #fff; }
.tool__mark svg { width: 1.15rem; height: 1.15rem; }

.tool__name {
  grid-area: name;
  font-family: var(--display);
  font-weight: 600;
  font-size: 1.02rem;
  letter-spacing: -.003em;
  line-height: 1.3;
}
.tool__desc {
  grid-area: desc;
  font-size: .845rem;
  line-height: 1.45;
  color: var(--muted);
}

/* ----------------------------------------------------------- options */

.options { display: flex; flex-direction: column; gap: 1.15rem; margin-bottom: 1.5rem; }
.options:empty { margin-bottom: .5rem; }

.field { display: flex; flex-direction: column; gap: .4rem; max-width: 30rem; }
/* Segmented rows need the room to stay on one line; a page range needs far
   less, and a short box tells you a short answer is expected. */
.field--wide { max-width: none; }
.field--narrow { max-width: 15rem; }
.field--narrow .field__help { width: max-content; max-width: 26rem; }
.field__label { font-size: .88rem; font-weight: 600; }
.field__help { font-size: .82rem; color: var(--muted); }

.input {
  font-family: var(--body);
  font-size: .95rem;
  padding: .68rem .85rem;
  border: 1px solid var(--rule);
  border-radius: 8px;
  background: var(--sheet);
  color: var(--ink);
  width: 100%;
}
.input:focus { outline: 2px solid var(--cloth); outline-offset: -1px; border-color: var(--cloth); }
.input--mono { font-family: var(--mono); letter-spacing: .04em; }

.password { position: relative; display: flex; }
.password .input { padding-right: 4.2rem; }
.password__toggle {
  position: absolute;
  right: .4rem;
  top: 50%;
  transform: translateY(-50%);
  background: none;
  border: 0;
  font-family: var(--mono);
  font-size: .72rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--cloth);
  cursor: pointer;
  padding: .35rem .5rem;
  border-radius: 5px;
}
.password__toggle:hover { background: var(--cloth-wash); }

/* Segmented choices, used for split mode and compression level. */
.choices { display: flex; flex-wrap: wrap; gap: .5rem; }
.choice {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: .1rem;
  padding: .62rem .95rem;
  border: 1px solid var(--rule);
  border-radius: 8px;
  background: var(--sheet);
  cursor: pointer;
  font-size: .9rem;
  transition: border-color .18s var(--ease), background .18s var(--ease);
}
.choice input { position: absolute; opacity: 0; pointer-events: none; }
.choice:hover { border-color: var(--cloth-lift); }
.choice:has(input:checked) { border-color: var(--cloth); background: var(--cloth-wash); box-shadow: 0 0 0 1px var(--cloth); }
.choice:has(input:focus-visible) { outline: 2px solid var(--cloth); outline-offset: 2px; }
.choice strong { font-weight: 600; }
.choice small { color: var(--muted); font-size: .78rem; }

/* --------------------------------------------------------- run + result */

.runbar { display: flex; align-items: center; gap: 1.1rem; flex-wrap: wrap; }

.runbar__status {
  font-family: var(--mono);
  font-size: .8rem;
  color: var(--muted);
  letter-spacing: .03em;
}
.runbar__status.is-working { color: var(--cloth); }
.runbar__status.is-working::after {
  content: "";
  display: inline-block;
  width: .5rem;
  animation: dots 1.2s steps(4, end) infinite;
}
@keyframes dots { 0% { content: ""; } 25% { content: "."; } 50% { content: ".."; } 75% { content: "..."; } }

/* Upload progress. Determinate while bytes are going out, then a sweep once
   the server takes over and there is nothing honest left to measure. */
.progress { margin-top: 1rem; max-width: 32rem; }

.progress__track {
  height: 5px;
  border-radius: 3px;
  background: var(--paper-deep);
  overflow: hidden;
}

.progress__bar {
  height: 100%;
  width: 0;
  border-radius: 3px;
  background: var(--cloth);
  transition: width .18s var(--ease);
}

.progress.is-indeterminate .progress__bar {
  width: 40%;
  animation: sweep 1.15s var(--ease) infinite;
}
@keyframes sweep {
  0%   { margin-left: -40%; }
  100% { margin-left: 100%; }
}
@media (prefers-reduced-motion: reduce) {
  .progress.is-indeterminate .progress__bar { width: 100%; animation: none; opacity: .5; }
}

/* A checkbox that needs room to explain itself. */
.toggle {
  display: flex;
  align-items: flex-start;
  gap: .75rem;
  max-width: 34rem;
  cursor: pointer;
}
.toggle input { position: absolute; opacity: 0; pointer-events: none; }

.toggle__box {
  flex: none;
  width: 1.15rem;
  height: 1.15rem;
  margin-top: .12rem;
  border: 1.5px solid var(--rule);
  border-radius: 5px;
  background: var(--sheet);
  display: grid;
  place-items: center;
  transition: background .18s var(--ease), border-color .18s var(--ease);
}
.toggle__box::after {
  content: "";
  width: .4rem;
  height: .68rem;
  border: solid #fff;
  border-width: 0 2px 2px 0;
  transform: rotate(45deg) scale(0);
  margin-top: -.15rem;
  transition: transform .16s var(--ease);
}
.toggle:hover .toggle__box { border-color: var(--cloth); }
.toggle input:checked + .toggle__box { background: var(--cloth); border-color: var(--cloth); }
.toggle input:checked + .toggle__box::after { transform: rotate(45deg) scale(1); }
.toggle input:focus-visible + .toggle__box { outline: 2px solid var(--cloth); outline-offset: 2px; }

.toggle__text strong { display: block; font-size: .92rem; font-weight: 600; }
.toggle__text small { display: block; font-size: .84rem; color: var(--muted); margin-top: .12rem; }

/* Language checkboxes are labels only — no second line to make room for. */
.choice--compact { padding: .5rem .85rem; }
.choice--compact strong { font-weight: 500; }

.result {
  display: flex;
  align-items: center;
  gap: 1.2rem;
  flex-wrap: wrap;
  margin-top: 1.5rem;
  padding: 1.15rem 1.3rem;
  background: var(--sheet);
  border: 1px solid var(--rule);
  border-left: 3px solid var(--foil);
  border-radius: var(--radius);
}
.result__info { flex: 1; min-width: 12rem; }

.result__dismiss {
  flex: none;
  background: none;
  border: 0;
  color: var(--muted);
  cursor: pointer;
  padding: .4rem;
  margin-right: -.35rem;
  line-height: 0;
  border-radius: 6px;
  transition: color .18s var(--ease), background .18s var(--ease);
}
.result__dismiss:hover { color: var(--alarm); background: rgba(156, 50, 38, .08); }
.result__name { font-family: var(--display); font-weight: 600; font-size: 1.02rem; }
.result__meta { font-family: var(--mono); font-size: .76rem; color: var(--muted); margin-top: .2rem; }

.alert {
  margin-top: 1.25rem;
  padding: .85rem 1.1rem;
  background: rgba(156, 50, 38, .07);
  border-left: 3px solid var(--alarm);
  border-radius: 6px;
  color: #7c2a20;
  font-size: .92rem;
}

/* --------------------------------------------------------------- how */

.how {
  max-width: var(--page);
  margin: 0 auto;
  padding: clamp(2.5rem, 6vw, 4rem) var(--gutter);
  border-top: 1px solid var(--rule);
}

.how__intro { margin-bottom: 2.5rem; }
.how__intro h2 { font-size: clamp(1.7rem, 3.6vw, 2.4rem); }

/* Numbered because these steps genuinely happen in this order. */
.steps {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
  gap: 2rem;
}
.steps li { border-top: 1px solid var(--ink); padding-top: 1rem; }
.steps__n {
  display: block;
  font-family: var(--mono);
  font-size: .74rem;
  letter-spacing: .16em;
  color: var(--foil);
  margin-bottom: .7rem;
}
.steps h3 { font-size: 1.06rem; margin-bottom: .45rem; }
.steps p { font-size: .92rem; color: var(--ink-soft); }

.how__note {
  margin-top: 2.5rem;
  max-width: 52ch;
  font-size: .88rem;
  color: var(--muted);
  padding-left: 1rem;
  border-left: 2px solid var(--rule);
}

/* --------------------------------------------------------- colophon */

.colophon {
  max-width: var(--page);
  margin: 0 auto;
  padding: 2rem var(--gutter) 3rem;
  border-top: 1px solid var(--rule);
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  font-size: .85rem;
  color: var(--muted);
}
.colophon strong { color: var(--ink); font-family: var(--display); }

.colophon__app { display: flex; align-items: baseline; gap: .55rem; flex-wrap: wrap; }
.colophon__app a { font-weight: 600; }
.colophon__app span {
  font-family: var(--mono);
  font-size: .72rem;
  letter-spacing: .04em;
  color: var(--muted);
}

/* ------------------------------------------------------- responsive */

@media (max-width: 900px) {
  .hero { grid-template-columns: 1fr; }
  .hero__stack { order: -1; }
  .dropzone { max-width: none; }
  .masthead__nav { gap: 1.1rem; font-size: .88rem; }
}

@media (max-width: 560px) {
  .thread { display: none; }
  .panel { padding-left: 0; }
  .panel__head .knot { display: none; }
  .hero__title { font-size: clamp(2rem, 9vw, 2.6rem); }
  .gathering { width: 9.5rem; height: 11.5rem; }
  .runbar { gap: .75rem; }
  .runbar .btn--lg { width: 100%; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
}
