/* Pleroma — design tokens measured off the reference: computed styles for the
   colours and type, and pixel sampling of a screenshot for the card, which is
   the only way the translucency and the true 352px width showed up. */

@font-face {
  font-family: 'DepartureMono';
  src: url('/static/fonts/DepartureMono-Regular.woff2') format('woff2');
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'PlantinNow';
  src: url('/static/fonts/PlantinNowVariable-Upright.woff2') format('woff2-variations'),
       url('/static/fonts/PlantinNowVariable-Upright.woff2') format('woff2');
  font-weight: 200 800; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'PlantinNow';
  src: url('/static/fonts/PlantinNowVariable-Italic.woff2') format('woff2-variations'),
       url('/static/fonts/PlantinNowVariable-Italic.woff2') format('woff2');
  font-weight: 200 800; font-style: italic; font-display: swap;
}

:root {
  --bg: #ebe7e4;
  --fg: #13110f;
  --chrome: #2c2825;
  --interactive: #5c5752;
  --interactive-hover: #ebe7e4;
  --interactive-hover-bg: #252f3d;
  --border: #5c5752;
  --shadow: #2e2a26;          /* the foliage cast, multiplied over the wall */
  /* Translucent, not solid: sampled across the reference card the interior
     swings about 30 levels as the shadow passes behind it. Solving
     card = a*fill + (1-a)*wall against those samples gives this fill at
     0.55 — it reproduces the measured pixels within two levels per channel.
     Making it opaque is what killed the effect in the first build. */
  --card-fill: #dacbc2;                     /* solid: the shadow above supplies the variation */
  --card-lift: #dfd3cc;                     /* the lighter top edge */
  --card-shadow: 0 10px 30px rgba(0, 0, 0, 0.22);

  --mono: 'DepartureMono', ui-monospace, monospace;
  --serif: 'PlantinNow', serif;
  --sans: 'Helvetica Neue', Helvetica, Arial, system-ui, sans-serif;

  --card-w: 352px;   /* the waitlist card; the sign-in card is .card.wide */
  --card-pad: 24px;
  --field-h: 36px;
  --inset: 24px;
  --stack: 12px;
}

/* AUTO follows the system; the toggle stamps data-theme to override it. */
@media (prefers-color-scheme: dark) {
  :root {
    --bg: #171513; --fg: #e8e3df; --chrome: #b3aca6;
    --interactive: #9a938c; --interactive-hover: #171513;
    --interactive-hover-bg: #cfd8e4; --border: #4a4540;
    --shadow: #000000;
    --card-fill: #342d29;
    --card-lift: #3a322d;
    --card-shadow: 0 10px 30px rgba(0, 0, 0, 0.45);
  }
}
:root[data-theme="light"] {
  --bg: #ebe7e4; --fg: #13110f; --chrome: #2c2825;
  --interactive: #5c5752; --interactive-hover: #ebe7e4;
  --interactive-hover-bg: #252f3d; --border: #5c5752;
  --shadow: #2e2a26;
  --card-fill: #dacbc2;
  --card-lift: #dfd3cc;
  --card-shadow: 0 10px 30px rgba(0, 0, 0, 0.22);
}
:root[data-theme="dark"] {
  --bg: #171513; --fg: #e8e3df; --chrome: #b3aca6;
  --interactive: #9a938c; --interactive-hover: #171513;
  --interactive-hover-bg: #cfd8e4; --border: #4a4540;
  --shadow: #000000;
  --card-fill: #342d29;
  --card-lift: #3a322d;
  --card-shadow: 0 10px 30px rgba(0, 0, 0, 0.45);
}

/* Cross-document transitions where the browser supports them: navigation
   becomes a short cross-fade instead of a hard cut to a blank frame. */
@view-transition { navigation: auto; }
::view-transition-old(root),
::view-transition-new(root) { animation-duration: 260ms; }
@media (prefers-reduced-motion: reduce) {
  ::view-transition-old(root),
  ::view-transition-new(root) { animation: none; }
}

* { box-sizing: border-box; }

html, body { height: 100%; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font-family: var(--mono);
  font-size: 14px;
  line-height: 20px;
  letter-spacing: 0.7px;
  overflow: hidden;             /* the reference page does not scroll */
  -webkit-font-smoothing: antialiased;
}

/* --- background stack ------------------------------------------------- */

#fx {
  position: fixed; inset: 0; width: 100%; height: 100%;
  object-fit: cover;
  z-index: 40;
  pointer-events: none;
  mix-blend-mode: multiply;
  /* 0.2, the value the reference declares. An earlier reading of 0.28 came
     from comparing two different frames of the same loop, which is not a
     comparison at all — it left every page about 20 levels too dark. */
  opacity: 0.2;
  transform: translateZ(0);
  opacity: 0.28;
  transition: opacity 400ms ease;
}
/* only the toggle turns it off — the default must not depend on script, or a
   failed script leaves the page with no background at all */
:root[data-fx="off"] #fx { opacity: 0; }
@media (prefers-color-scheme: dark) { #fx { mix-blend-mode: screen; } }
:root[data-theme="dark"] #fx { mix-blend-mode: screen; }
:root[data-theme="light"] #fx { mix-blend-mode: multiply; }

#grain {
  position: fixed; inset: 0;
  z-index: 30;
  pointer-events: none;
  opacity: 0.55;
  transform: translateZ(0);
  /* the paper tooth, drawn by the browser rather than built in script — it is
     painted with the first frame instead of appearing a moment later */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='0.30'/%3E%3C/svg%3E");
  background-repeat: repeat;
}

.skip {
  position: absolute; left: -9999px; top: 0;
  z-index: 200; padding: 8px 12px;
  background: var(--bg); color: var(--fg);
  border: 1px solid var(--border);
}
.skip:focus { left: var(--inset); top: var(--inset); }

/* --- corner mark ------------------------------------------------------ */

.mark {
  position: fixed; top: var(--inset); left: var(--inset);
  z-index: 120;
  /* The landing has no corner mark — its wordmark is the centred hero — so
     arriving at any other page makes this element appear from nothing at the
     top-left corner. Popping in is the flash; fading in is not. */
  animation: mark-in 280ms ease both;
}
@keyframes mark-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .mark { animation: none; }
}
/* the whole lockup measures 96x21 in the reference; the glyph is the square
   bracket block and the wordmark sits on the same optical baseline */
.mark a {
  display: inline-flex; align-items: center; gap: 7px;
  height: 21px;
  color: var(--fg); text-decoration: none;
}
.mark .glyph { width: 17px; height: 17px; fill: currentColor; display: block; }
.mark .wordmark {
  font-family: var(--serif);
  font-size: 21px; line-height: 21px;
  letter-spacing: -0.2px;
  font-weight: 600;
}

/* --- the card --------------------------------------------------------- */

/* #view exists only so htmx has something to swap; it must not become a box
   in the layout, or main's min-height resolves against it instead of the
   viewport and the card stops being centred. */
#view { display: contents; }

main {
  position: relative; z-index: 20;   /* under #fx (40): the shadow falls across the card */
  min-height: 100%;
  display: grid; place-items: center;
  padding: 88px var(--inset);
}
main:focus { outline: none; }

/* Translucent paper, no border. The shadows behind carry on across it, which
   is what makes it sit in the scene instead of on top of it. */
.card {
  width: 100%;
  max-width: var(--card-w);
  padding: var(--card-pad);
  border: 0;
  background: linear-gradient(180deg,
    var(--card-lift) 0%, var(--card-fill) 25%, var(--card-fill) 100%);
  box-shadow: var(--card-shadow);
}

/* The sign-in card is the wider of the two. Named --wide, NOT .wide: .wide is
   already the full-width button below, and putting both on one element made
   the card inherit the button's 36px height, 12px padding and transparent
   background — it stopped being a card at all. */
.card--wide { max-width: 448px; }

.title {
  margin: 0 0 var(--inset);
  font-family: var(--serif);
  font-style: italic;
  font-weight: 400;
  font-size: 24px;
  line-height: 24px;
  letter-spacing: -0.6px;
  color: var(--fg);
  text-align: center;
}

/* email + submit share one row; the input takes the remainder */
/* 356 card - 48 padding - 13 gap - 36 tick = the 259px field measured
   off the reference */
.row { display: flex; align-items: center; gap: 12px; }

#email {
  flex: 1 1 auto; min-width: 0;
  height: var(--field-h);
  padding: 6px 12px;
  border: 1px solid var(--border);
  border-radius: 0;
  background: var(--bg);
  color: var(--fg);
  font-family: var(--serif);
  font-size: 16px;
  letter-spacing: normal;
  transition: border-color 150ms ease;
}
#email::placeholder { color: var(--fg); opacity: 0.45; }
#email:focus-visible { outline: none; border-color: var(--fg); }
#email[aria-invalid="true"] { border-color: #9d3b32; }

.check {
  flex: 0 0 auto;
  width: var(--field-h); height: var(--field-h);
  display: inline-flex; align-items: center; justify-content: center;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--interactive);
  cursor: pointer;
  transition: color 150ms ease, background-color 150ms ease;
}
/* 21px, not 18: measured against the reference the glyph is 14x10 with 40 ink
   pixels; at 18px with a 1.6 stroke mine was 12x9 with 22 — half the ink, so
   it anti-aliased into the card instead of reading as a mark. */
.check svg { width: 21px; height: 21px; display: block; }
/* Hidden until the field has a value: empty, the field takes the whole row,
   which is how the reference card sits before you type. */
.row:has(#email:placeholder-shown) .check { display: none; }
.check:hover { color: var(--fg); }
.check:focus-visible { outline: none; border-color: var(--border); }
.check[disabled] { opacity: 0.5; pointer-events: none; }

.err {
  margin: var(--stack) 0 0;
  font-size: 12px; line-height: 16px;
  color: #9d3b32;
}

/* Measured off the reference: the line's ink is 299px inside 304px of card
   content. 11px (an earlier reading, taken from a wrapper rather than the
   text) was far too small. */
.back {
  margin: var(--stack) 0 0;
  font-size: 14px;
  line-height: 20px;
  color: var(--fg);
  text-align: center;
  /* one line: the reference sets it 299px wide inside 304px of content, so it
     only just fits, and left to wrap it splits into two and makes the card
     20px taller than it should be */
  white-space: nowrap;
}
/* Below 380px that nowrap costs more than it buys. main is a grid whose item
   cannot shrink below its own min-content, so the unbreakable line gives the
   card a hard 348px floor; add the 16px inset on each side and the card is
   wider than a 320px phone. The page then scrolls sideways — the whole layout,
   not just the card — which is the one thing a reader notices immediately.
   Letting the line break costs the 20px of card height the note above is
   avoiding. On a 320px screen that is a trade worth making every time.
   380px is where it stops mattering: 380 - 32 = 348, exactly the floor. */
@media (max-width: 380px) {
  .back { white-space: normal; }
}

/* the brackets are part of the label — never let one wrap away from it */
.back a { color: var(--interactive); text-decoration: none;
          letter-spacing: 0.7px; white-space: nowrap; }
.back a:hover { color: var(--fg); }

/* success state — mono, centred, same panel */
.done { text-align: center; color: var(--fg); }
.done p { margin: 0; font-size: 14px; line-height: 28px; }

/* --- bottom chrome ---------------------------------------------------- */

.chrome {
  position: fixed; left: 0; right: 0; bottom: var(--inset);
  z-index: 120;
  display: flex; align-items: center; justify-content: space-between;
  padding: 0 var(--inset);
  pointer-events: none;
}
.chrome > * { pointer-events: auto; }

.co {
  font-size: 14px; letter-spacing: 0.7px;
  color: var(--chrome); text-decoration: none;
}
.co:hover { color: var(--fg); }

.controls { display: flex; align-items: center; gap: 16px; }

.controls button {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 0 4px;
  border: 0; background: transparent;
  font: inherit; font-size: 14px; letter-spacing: 0.7px;
  text-transform: uppercase;
  color: var(--chrome);
  cursor: pointer;
}
.controls button:hover { color: var(--fg); }
.controls .ico { font-size: 13px; }

/* Touch targets.
   The FX and theme buttons are 20px tall, which is a hard thing to hit with a
   thumb. Their drawn size is the reference's and is deliberate, so the hit
   area is grown with a pseudo-element rather than with padding: the box a
   finger has to find gets bigger and not one pixel of the design moves.
   Growing them for real is not available anyway — .chrome is a fixed bar that
   centres its children, so a 44px button makes the whole bar taller.

   44px is Apple's minimum and the number styles.css already uses for the nav
   links on small screens, so the two halves agree.

   The tick grows upward and downward only. It sits flush against the email
   field, and widening it would put its hit area over the field's right edge,
   where a tap meant for the field would submit the form instead. The 36px
   submit buttons elsewhere are left alone: they are 300px wide and nobody
   misses them.

   Selected by child rather than by element: the bar holds two buttons and a
   link, all three drawn the same size, and a rule that said `button` gave two
   of them a thumb-sized target and left the third at 20px. */
.controls > button,
.controls > a,
.chrome > a,
.mark a,
.check { position: relative; }

.controls > button::after,
.controls > a::after,
.chrome > a::after,
.mark a::after,
.check::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  width: 100%;
  height: max(100%, 44px);
}

.controls > button::after,
.controls > a::after,
.chrome > a::after,
.mark a::after { width: max(100%, 44px); }

.herald {
  padding: 0 4px;
  font-size: 14px; font-weight: 500; letter-spacing: 0.7px;
  text-transform: uppercase; text-decoration: none;
  background: var(--interactive-hover-bg);
  color: var(--interactive-hover);
  transition: background-color 150ms ease, color 150ms ease;
}
.herald:hover { background: transparent; color: var(--fg); }

/* --- small screens ---------------------------------------------------- */

@media (max-width: 640px) {
  :root { --inset: 16px; }
  .mark .wordmark { font-size: 22px; }
  main { padding: 80px var(--inset); }
  .card { padding: 20px; }
  /* the reference hides the company mark on mobile; the controls stay */
  .co { display: none; }
  .chrome { justify-content: flex-end; }
  .controls { gap: 12px; }
}

@media (prefers-reduced-motion: reduce) {
  #fx { animation: none; }
  * { transition-duration: 1ms !important; }
}

/* --- the landing composition ------------------------------------------ */
/* wordmark on the centre of the frame, the way in pushed below it — the
   offset is half the top margin because the layer is centred, so it tracks
   the viewport the way the reference does */

/* carried by <main>, not <body>: the body survives every swap, so a
   layout hook there would keep applying to the page that replaced it */
main.landing { display: block; padding: 0; }

.hero-mark,
.hero-enter {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  margin: 0;
}

.hero-mark {
  font-family: var(--serif);
  font-size: 33px; line-height: 1;
  font-weight: 600; letter-spacing: 1px;
  color: var(--fg);
}

.hero-enter { margin-top: clamp(280px, 40vw, 400px); }

.enter {
  display: inline-flex; align-items: center; justify-content: center;
  height: 36px; padding: 6px 16px;
  font-size: 14px; font-weight: 500; letter-spacing: 0.7px;
  text-transform: uppercase; text-decoration: none;
  color: var(--interactive);
  transition: color 150ms ease, background-color 150ms ease;
}
.enter:hover { color: var(--interactive-hover); background: var(--interactive-hover-bg); }

/* --- the sign-in card -------------------------------------------------- */

.title.start { text-align: start; }

/* every control in this card is one full-width row, 12px apart */
#signin > * { margin-top: var(--stack); }
/* The title's bottom margin does NOT collapse with the field's top margin —
   the field is an inline-block, and inline-block margins never collapse with
   siblings — so the two add up and everything below sat 12px too low. Halve
   the title's, and 12 + 12 gives the 24px gap the reference has. */
#signin > .title { margin-top: 0; margin-bottom: var(--stack); }
#signin #email { width: 100%; }

.wide {
  display: flex; align-items: center; justify-content: center;
  width: 100%; height: var(--field-h);
  padding: 0 12px;
  border: 1px solid var(--border);
  background: transparent;
  color: var(--interactive);
  font: inherit; font-size: 14px; font-weight: 500; letter-spacing: 0.7px;
  text-decoration: none;
  cursor: pointer;
  transition: color 150ms ease, background-color 150ms ease;
}
.wide:hover { color: var(--interactive-hover); background: var(--interactive-hover-bg); }
.wide:focus-visible { outline: 2px solid var(--fg); outline-offset: 2px; }
.wide[disabled], .wide[aria-disabled="true"] { opacity: 0.5; pointer-events: none; }

/* the rule runs past the padding to the card's own edges */
hr.bleed {
  width: calc(100% + 2 * var(--card-pad));
  margin-left: calc(-1 * var(--card-pad));
  border: 0; border-top: 1px solid var(--border);
  opacity: 0.3;
}
