/* ============================================================
   kathmandu.ing
   One face: Grug Hand, from HandDrawnFont.
   Four colours: ink, paper, cobalt, pink eraser. Nothing else.
   ============================================================ */

@font-face {
  font-family: "Grug Hand";
  src: url("fonts/GrugHand-Light.woff2") format("woff2");
  font-weight: 300; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Grug Hand";
  src: url("fonts/GrugHand-Regular.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Grug Hand";
  src: url("fonts/GrugHand-Book.woff2") format("woff2");
  font-weight: 450; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Grug Hand";
  src: url("fonts/GrugHand-Medium.woff2") format("woff2");
  font-weight: 500; font-style: normal; font-display: swap;
}

:root {
  --ink:    #282828;
  --paper:  #f9f6ef;
  --cobalt: #193497;
  --pink:   #eda398;

  /* the press is set up one way; only the stock changes */
  --ground:    var(--paper);
  --on-ground: var(--ink);
  --edge:      var(--ink);
  --quiet:     rgba(40, 40, 40, .72);

  /* whatever reads against the stock the wall is printed on */
  --accent: var(--cobalt);

  --hand: "Grug Hand", "Bradley Hand", "Segoe Print", "Chalkboard SE", cursive;
  --wall: 76rem;
  --gap: .7rem;

  /* drawably draws the edges now, so it prints in the same four colours as
     everything else. These are written as the site's own tokens rather than as
     literals, and --ground, --on-ground and --accent all flip in the dark block
     below — so the pen follows the stock with nothing restated and nothing to
     drift. --error and --success ship a red and a green by default and are
     redirected here even though no control reaches those states today; a fifth
     colour should not be one setState away. There is no property behind
     .drawably-button--neutral's grey, so that tone is simply never used, and
     the rule is overridden below in case it ever is. */
  --drawably-stroke:  var(--on-ground);
  --drawably-fill:    var(--on-ground);
  --drawably-paper:   var(--ground);
  --drawably-error:   var(--accent);
  --drawably-success: var(--accent);
  --drawably-width: 2;
}

/* The viewer's own setting decides. Light is the default — a print is
   ink on paper — and dark is the same run printed on ink instead. */
@media (prefers-color-scheme: dark) {
  :root {
    --ground:    var(--ink);
    --on-ground: var(--paper);
    --edge:      var(--paper);
    --quiet:     rgba(249, 246, 239, .74);
    --accent:    var(--pink);
  }
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--ground);
  color: var(--on-ground);
  font-family: var(--hand);
  font-feature-settings: "calt" 1, "rand" 1;
  font-variant-ligatures: contextual;
  -webkit-text-size-adjust: 100%;
}

/* ---------- the masthead plate ---------- */
/* The cobalt is drawn, not painted: a filled rough rect whose box starts well
   outside the viewport on three sides, so the only edge anybody sees is the
   torn bottom one. The extra 6px of bottom padding is the deckle's room —
   without it the wobble eats into the wordmark's descenders. */
.band {
  position: relative;
  isolation: isolate;
  --plate: var(--cobalt);
  --drawably-stroke: var(--paper);
  --drawably-fill:   var(--paper);
  color: var(--paper);
  padding: clamp(2.4rem, 7vw, 4.6rem) 1.1rem calc(clamp(2rem, 5vw, 3.4rem) + 6px);
}
/* the second colour lands a hair low, the way it does on press */
.band .hand-fill.off { fill: var(--pink); stroke: var(--pink); }
.band-in { max-width: var(--wall); margin: 0 auto; }

.mark-row {
  display: flex;
  align-items: center;
  gap: .12em;
  font-size: clamp(3rem, 13vw, 9rem);
}

/* The drawing arrives from faces.js after the first paint, so the box has to
   already be the right size when it lands. An unsized .stupa is zero wide and
   the wordmark beside it jumps the whole width of a stupa when the mark
   appears — measured at 118px on a wide screen, and the h1 is the largest
   thing on the page. .82em is what the SVG itself is set to, just below. */
.stupa { flex: none; line-height: 0; width: .82em; height: .82em; }
.stupa svg {
  display: block;
  width: .82em;
  height: .82em;
  fill: none;
  stroke: var(--paper);
  stroke-linecap: round;
  stroke-linejoin: round;
  overflow: visible;
}

.mark {
  position: relative;
  margin: 0;
  font-weight: 300;
  font-size: 1em;
  line-height: .9;
  letter-spacing: -.015em;
  text-wrap: balance;
}
/* the second colour lands a hair off register, the way it does on press */
.mark .ghost {
  position: absolute;
  inset: 0;
  color: var(--pink);
  transform: translate(.03em, .032em);
  user-select: none;
}
.mark .fore { position: relative; }
/* The full stop is the Instagram link: a thumbed smudge of the second colour
   with the glyph pressed into it, sitting exactly where the dot was so the
   wordmark keeps its own kerning and wraps like the text it is. */
.mark .dot {
  position: relative;
  display: inline-block;
  margin: 0 .1em 0 .07em;
  font-weight: 500;
  text-decoration: none;
  color: var(--pink);
}
.mark .stop { color: transparent; }
.mark .ghost .dot { visibility: hidden; }

.smudge {
  position: absolute;
  left: 50%;
  bottom: 0;
  width: .46em;
  height: .46em;
  transform: translate(-50%, 6%) rotate(-5deg);
  transition: transform .24s cubic-bezier(.2, .8, .3, 1);
  pointer-events: none;
}
.smudge svg { display: block; width: 100%; height: 100%; overflow: visible; }
.smudge .blob { fill: var(--pink); stroke: none; }
.smudge use { fill: none; stroke: var(--ink); stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round; }

/* a hit area worth aiming at, without disturbing the letters */
.mark .dot::after { content: ""; position: absolute; inset: -.18em -.16em -.1em; }
.mark .dot:hover .smudge { transform: translate(-50%, 6%) rotate(6deg) scale(1.1); }
/* Focus was a crisp rectangle sitting in the middle of the wordmark. It is a
   drawn ring now — drawablyCircle loops an ellipse around the stop the way a
   hand would — kept hidden until the keyboard arrives, exactly as the outline
   was. 3px because the library drops text decorations to 1.5px for body copy,
   which is too thin to be a focus indicator. */
.mark .dot { --drawably-width: 3; }
.mark .dot > .drawably-svg { visibility: hidden; }
.mark .dot:focus-visible > .drawably-svg { visibility: visible; }
/* and if the ring was never drawn, the ring is still the outline */
.mark .dot:not(.drawably-host):focus-visible { outline: 2px solid var(--paper); outline-offset: .06em; }




/* ---------- icons ----------
   Grug Hand ships no icons, so these are drawn to its own spec: one stroke,
   six percent of the em, butt caps. */
.sprite { display: none; }

.icon {
  width: 1em;
  height: 1em;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: butt;
  stroke-linejoin: round;
  vertical-align: -.14em;
}

/* ---------- the drawn layers ----------
   Everything with an edge on this page is drawn by a pen now, and there are
   only three kinds of drawing.

   FILL   a colour whose boundary is itself drawn: the card plates, the
          masthead band, the toast. A rough rounded rect filled AND stroked in
          the same colour, so the fill boundary gets a furry deckle rather than
          a clean cut. This is the one that matters: drawably draws an outline
          only, so a sketched frame over `background: var(--pink)` is still a
          crisp pink rectangle with a wobbly line floating near it.
   FRAME  a drawn outline, from drawably's own attachers.
   RULE   a drawn line, where a border-top or a border-bottom used to be.

   The layers are prepended into the host by sketch.js and carry their own
   classes rather than .drawably-svg, so they inherit neither the library's
   path rules nor its boil animation. z-index puts the fill below drawably's
   own chrome at -1 whatever order the two were prepended in, which is the
   whole reason it is stated here rather than left to the DOM. Nothing in
   sketch.js names a colour: it draws the shape and reads --plate from here,
   so the four plates stay in one file. */
.hand-plate,
.hand-rule {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
  pointer-events: none;
  animation: none;   /* nothing in these boils; see the note by .card */
}
.hand-plate { z-index: -2; }
.hand-rule  { z-index: -1; }

.hand-fill {
  fill:   var(--plate, transparent);
  stroke: var(--plate, transparent);
  stroke-width: 4;   /* the deckle: a fill boundary with a torn edge */
  stroke-linejoin: round;
}

.hand-rule path {
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* An <hr> with nothing drawn on it is a crisp inset line, which is the exact
   thing being removed, so the element is flattened here and not only by the
   library's own .drawably-divider. color: inherit is not tidiness — the UA
   gives an <hr> `color: gray`, measured at rgb(128,128,128), and the drawn
   line rides currentColor, so without this every rule on the site is a fifth
   colour. */
.rule {
  display: block;
  height: 10px;
  margin: 0;
  border: 0;
  color: inherit;
}

/* ---------- focus, with no rectangles in it ----------
   Nine outlines used to live in this file. Every one of them is now a drawn
   ring: drawably's own .drawably-focus layer where an attacher provides one
   (the buttons, the input and textarea boxes), and .hand-focus — the same
   roughRoundedRect the attachers draw with, laid inside the box — for the
   bare controls that have none.

   Two deliberate departures, both because this is an accessibility
   requirement rather than decoration. The first is restyling a vendor path,
   which the library's own rules say not to do: .drawably-focus is hardcoded to
   1.5px, and a 1.5px focus indicator on a wobbly line is not one. The second
   is every :not() below. A drawn focus ring that was never drawn is no focus
   ring at all, so each control keeps a real outline that appears only in the
   state where nothing sketched it — the module failing, or a page that runs no
   script. In the intended state not one of them can match. */
.drawably-svg .drawably-focus,
.hand-focus path { stroke-width: 3; }

.hand-focus {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
  pointer-events: none;
  animation: none;
  visibility: hidden;
  z-index: 1;   /* the one drawn layer that sits above, not behind */
}
.hand-focus path {
  fill: none;
  stroke: var(--accent);
  stroke-linecap: round;
  stroke-linejoin: round;
}
:is(.open-write, .bar-btn):focus-visible > .hand-focus,
.card:focus-visible > .hand-focus,
.field:has(:focus-visible) > .hand-focus { visibility: visible; }

/* The vendor shows a ring with a DESCENDANT selector,
   `.drawably-host:is(:focus-visible, :has(:focus-visible)) .drawably-focus`.
   #bar is itself a drawably host wrapping five more, so focusing the tag field
   lit nine rings at once and the whole bar came up. Re-hide any ring whose own
   host is not the focused one. 0,4,0 beats the vendor's 0,2,0, and it themes
   rather than editing vendor/. */
.drawably-host:not(:focus-visible):not(:has(:focus-visible))
  > .drawably-svg .drawably-focus { visibility: hidden; }

/* Deleting an outline rule does not leave a control with no ring — it leaves
   it with the browser's own, which is the squarest rectangle on the page and
   was measured sitting on top of every drawn one. Every control whose ring is
   drawn says so here. The fallbacks further down are all more specific, so
   they still win in the state where nothing drew anything. */
:is(.open-write, .bar-btn):focus-visible,
:is(.mark .dot):focus-visible,
.field :focus-visible { outline: none; }

/* ---------- drawably, in this typeface ----------
   vendor/drawably/style.css hardcodes Inter on .drawably-host, which is the
   card and not just the control inside it, so without this every card loses
   Grug Hand. .drawably-button restates it, and .drawably-badge uses the font
   shorthand, which resets size and weight along with the family. */
.drawably-host,
.drawably-button { font-family: inherit; }
.drawably-badge { font: inherit; }

/* the one tone with no custom property behind it. It is never passed; this is
   here so a fifth colour cannot arrive by someone passing it later. */
.drawably-button--neutral {
  --drawably-stroke: var(--on-ground);
  --drawably-fill:   var(--on-ground);
}

/* ---------- the run ---------- */
.wall {
  max-width: var(--wall);
  margin: 0 auto;
  /* The toast is fixed 1.2rem off the bottom and fires from a save button, so
     the button that has focus is the one it can land on top of. 6rem is enough
     that nothing focusable can sit under it at the end of the wall. */
  padding: var(--gap) 1.1rem 6rem;
}

.grid {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(18.5rem, 1fr));
  gap: var(--gap);
}

.card[hidden] { display: none; }

/* The border and the overflow are both gone. The border was the box. The clip
   was worse than the border: it sliced the drawn edge flat at the card's own
   boundary, which puts a ruled line back at the exact place one was removed.
   Nothing depended on it — .card-text does its own clipping.
   The 1.5px the border occupied, plus the 3px the sketch is inset by, is paid
   back in padding, so the type sits the same distance inside the edge as it
   did and fit() lands on the same size. */
.card {
  display: flex;
  flex-direction: column;
  min-height: 20.5rem;
  padding: 1.3rem 1.4rem 1.25rem;
  position: relative;
  isolation: isolate;   /* the plate is a negative-z child; keep it in here */
  --drawably-stroke: currentColor;
  --drawably-fill:   currentColor;
}

/* Four plates, and they print the same whatever the stock. --plate is the
   colour the drawn fill is given; the foreground stays a real declaration
   because the whole card rides currentColor. */
.card[data-tone="0"] { --plate: var(--ink);    color: var(--paper); }
.card[data-tone="1"] { --plate: var(--paper);  color: var(--ink); }
.card[data-tone="2"] { --plate: var(--cobalt); color: var(--paper); }
.card[data-tone="3"] { --plate: var(--pink);   color: var(--ink); }

/* A drawn fill edge IS the edge, so a sketched outline inside it in the same
   foreground colour is a second frame around the first. The outline is only
   wanted where the plate cannot be seen against the stock: paper on paper in
   light, ink on ink in dark. --drawably-width: 0 renders no stroke at all, so
   this is one number rather than an attach-time decision, and it follows the
   viewer's setting with no listener and no re-sketch.
   It is set on the card's own sketch rather than on the card, because the
   property inherits: on .card it also reached the rule in the foot, the save
   button and the links, and every one of them came out at zero width. */
.card > .drawably-svg { --drawably-width: 0; }
.card[data-tone="1"] > .drawably-svg { --drawably-width: 2; }   /* paper on paper */
@media (prefers-color-scheme: dark) {
  .card[data-tone="1"] > .drawably-svg { --drawably-width: 0; }
  .card[data-tone="0"] > .drawably-svg { --drawably-width: 2; } /* ink on ink */
}

/* The wall repeats, and a wall that shimmers reads as unstable rather than as
   hand-drawn, so the cards are sketched once and held. boil: 0 at the attacher
   only stops the extra path variants being emitted — the animation is declared
   unconditionally on .drawably-svg and keeps ticking a custom property on every
   card for nothing. This switches off an animation that drives nothing; it does
   not restyle a path. The bar and the controls in it still boil. */
.card:not(.card-open) .drawably-svg { animation: none; }

/* A printed card takes focus so the keyboard lands on it rather than on the
   top of the document. The ring is drawn now: the sketch thickens and goes to
   the plate's own foreground, which is 13.66:1 on ink and paper, 9.83:1 on
   cobalt and 7.23:1 on pink — every one past the 3:1 a focus indicator has to
   make. Note that nothing gives a card a tabindex today, so this cannot
   currently fire; it is kept because the rule and its ring should exist the
   day one does. */
.card:focus-visible > .drawably-svg { --drawably-width: 3.5; }
.card:not(:has(> .hand-plate)):focus-visible {
  outline: 2px solid currentColor;
  outline-offset: -5px;
}

.tag {
  align-self: flex-end;
  font-size: .74rem;
  font-weight: 500;
  letter-spacing: .16em;
  text-transform: uppercase;
  opacity: .85;
  min-height: 1.1em;
  text-align: right;
  max-width: 80%;
  overflow-wrap: break-word;
}

.card-text {
  flex: 1 1 auto;
  margin: .8rem 0 .55rem;   /* the drawn rule brings 5px of its own above it */
  font-size: 1.9rem;         /* JS trims this down until the card holds it */
  line-height: 1.16;
  font-weight: 400;
  overflow: hidden;
  overflow-wrap: break-word;
}

/* A CSS underline is a ruled line, and the pen draws these instead — one
   drawing per line the link wraps onto, re-sketching under the cursor, which
   is what the thickness change used to say. The rule below is the state before
   the pen reaches a link and the state if it never does: a link marked in no
   way at all is indistinguishable from the sentence around it. */
.card-text a { color: inherit; text-decoration: none; }
.card-text a:not(.drawably-host) {
  text-decoration: underline;
  text-underline-offset: .16em;
  text-decoration-thickness: 1.5px;
}
.card-text a:not(.drawably-host):hover { text-decoration-thickness: 3px; }

/* A link with no rule of its own falls back to the browser's focus ring, which
   is rgb(0,95,204) in Chrome: a fifth colour, and the last crisp rectangle
   anywhere on the site in any state. The underline is already drawn, so thicken
   that and keep the outline in the palette for the case where nothing drew it. */
.card-text a:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  text-decoration-thickness: 3px;
}
.card-text a.drawably-host:focus-visible { outline: none; }

.card-foot {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: .75rem;
  /* the rule is an <hr> above this, drawn by drawablyDivider. Its line sits
     5px down inside a 10px box, so the padding pays back only the rest. */
  padding-top: .2rem;
}

.sig {
  display: flex;
  align-items: center;
  gap: .5rem;
  min-width: 0;
  font-size: 1.05rem;
  font-weight: 450;
  line-height: 1.2;
  overflow-wrap: anywhere;
}

/* Nobody uploads a photograph here. The name draws its own face — same name,
   same face, every time, and nothing is stored to make that true. */
.face {
  width: 2.5rem;
  height: 2.5rem;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-linecap: round;
  stroke-linejoin: round;
  overflow: visible;
}

.share-btn {
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  font-family: var(--hand);
  font-size: .76rem;
  font-weight: 500;
  letter-spacing: .14em;
  text-transform: uppercase;
  text-decoration: none;   /* it is an <a> on the 404 page, a <button> here */
  color: inherit;
  background: transparent;
  border: 0;   /* not "no longer 1.5px": a bare <button> is a 2px outset box */
  /* the frame is drawn; the extra side padding is the border's 1.5px plus the
     room the wobble needs to sit clear of the label */
  padding: .34rem .75rem .42rem;
  cursor: pointer;
}
.share-btn .icon { font-size: 1.15em; vertical-align: 0; }
/* The four hover swaps are gone, and they were the worst of it: a solid fill
   painted behind a sketched frame is a crisp rectangle inside a drawn one,
   fifteen times over. drawably's own hover says the same thing better — it
   lifts, washes the inside with the stroke at 10%, and re-draws the frame
   under the cursor. */
.share-btn:not(.drawably-host):focus-visible { outline: 2px solid currentColor; outline-offset: 3px; }

.card.fresh { animation: press .45s cubic-bezier(.2, .8, .3, 1) both; }
@keyframes press {
  from { opacity: 0; transform: translateY(-8px) scale(.985); }
  to   { opacity: 1; transform: none; }
}

/* ---------- the invitation ---------- */
/* The dashed strip the wall opens with is a drawn frame now. drawably has no
   dashed primitive, and a dash array laid over a wobbly path reads as a fault
   in the pen rather than as a dash, so the dash is let go: on a wall where
   every printed card is a filled plate, the bar being the one unfilled outline
   already says it is not printed yet. overflow: hidden went with it — .drawer-in
   and the write half do the clipping that was actually needed, and this one
   only sliced the frame flat down one side. */
.card-open {
  grid-column: 1 / -1;
  min-height: 0;
  padding: 0;
  color: var(--on-ground);
  display: block;
}
/* on the bar's own sketch, not on the bar: the properties inherit, and set on
   the element they reached the drawer's rules, the field frames and the print
   button too — hovering "write one" turned the whole drawer accent-coloured */
.card-open > .drawably-svg {
  --drawably-stroke: var(--on-ground);
  --drawably-width: 2;   /* .card zeroes it for the plated cards, and this is one */
}

.bar-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  transition: grid-template-columns .42s cubic-bezier(.2, .9, .28, 1);
}
.card-open.searching .bar-row { grid-template-columns: 0fr 1fr; }

/* The drawer opens by growing its own grid track — the one way to animate to
   a height nobody has measured. */
.bar-drawer {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows .52s cubic-bezier(.2, .9, .28, 1);
}
.card-open.writing .bar-drawer { grid-template-rows: 1fr; }
.drawer-in { min-height: 0; overflow: hidden; }
/* The drawer's top rule was a dashed border-top applied only while writing.
   It is a drawn line on an <hr> inside the drawer now, and it needs no such
   condition: the track is 0fr and this clips, so the line is simply not on
   screen until the drawer opens. Nothing hides it, deliberately — display:
   none would measure it at nothing and the pen would draw it the wrong size. */
/* the frame answers the pointer, the way the border-colour used to */
.card-open:has(.open-write:hover, .bar-btn:hover) > .drawably-svg { --drawably-stroke: var(--accent); }

.bar-half { min-width: 0; }
/* The write half collapses to nothing when the search opens and its label does
   not wrap, so that one still clips. The search half no longer does: it holds
   a drawn field box, and a clip there would cut the wobble back into a
   straight edge. The split between the two is a drawn line on this half's
   left, which has nothing to sit on while the other half is collapsed. */
.bar-half.open-write { overflow: hidden; }
.bar-search { position: relative; }
.card-open.searching .bar-search > .hand-rule { visibility: hidden; }
.card-open.searching .open-write { opacity: 0; transition: opacity .18s ease; }

.open-write,
.bar-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: .5rem;
  width: 100%;
  padding: .62rem 1rem .72rem;
  font-family: var(--hand);
  font-size: 1.05rem;
  font-weight: 450;
  letter-spacing: .02em;
  white-space: nowrap;
  color: inherit;
  background: transparent;
  border: 0;
  cursor: pointer;
  transition: color .18s ease;
}
.open-write .icon,
.bar-btn .icon {
  font-size: 1.35em;
  stroke-width: 1.5;
  vertical-align: 0;
  transition: transform .18s cubic-bezier(.2, .8, .3, 1);
}
.open-write:hover,
.bar-btn:hover { color: var(--accent); }
.open-write:hover .icon { transform: translateX(-2px) rotate(-4deg); }
.bar-btn:hover .icon { transform: scale(1.08) rotate(-6deg); }
/* These two are bare buttons with no attacher on them — the bar already
   carries a frame and a button frame inside it would be a box in a box — so
   the drawn focus ring is .hand-focus, laid inside the box because the write
   half clips and a ring cut off at the clip is a straight edge again. The
   outline below is the state where nothing drew one. */
:is(.open-write, .bar-btn) { position: relative; }
:is(.open-write, .bar-btn):not(:has(> .hand-focus)):focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -4px;
}

/* the search half opens into itself */
.bar-search { display: flex; align-items: center; }
.bar-search .bar-btn { width: auto; flex: none; }
.card-open.searching .bar-btn { color: var(--accent); padding-right: .4rem; }
.card-open.searching .bar-label { display: none; }

.search-input {
  flex: 1 1 auto;
  min-width: 0;
  width: 0;
  opacity: 0;
  pointer-events: none;
  font-family: var(--hand);
  font-feature-settings: "calt" 1, "rand" 1;
  font-size: 1.05rem;
  color: inherit;
  background: transparent;
  border: 0;
  padding: .5rem .9rem .6rem 0;
  transition: opacity .2s ease .12s;
}
.card-open.searching .search-input { opacity: 1; pointer-events: auto; }
.search-input::placeholder { color: var(--quiet); opacity: 1; }
/* The field sits in a wrapper the library frames, which brings both the drawn
   box and the .drawably-focus layer that replaces the outline this rule used
   to be. The collapse is repeated on the wrapper so the sketch fades out with
   the field instead of leaving an empty drawn box in the bar at all times, and
   the padding is restated at two classes because the vendor's own 8px 12px
   beats a single-class selector. */
.search-box {
  display: block;
  flex: 1 1 auto;
  width: 0;
  min-width: 0;
  opacity: 0;
  pointer-events: none;
  transition: opacity .2s ease .12s;
}
.card-open.searching .search-box { opacity: 1; pointer-events: auto; }
.bar-search .search-box .search-input { padding: .45rem .7rem .55rem; }
/* --accent is 9.83:1 on paper and 7.23:1 on ink, either way past the 3:1 a
   focus indicator needs. Only reachable if the field was never framed. */
/* was `.bar-search > .search-input`, which the .search-box wrapper broke.
   Scoped to "nothing drew a ring here", so it cannot fight the drawn one. */
.bar-search .search-input:focus-visible:not(.drawably-host *) { outline: 2px solid var(--accent); outline-offset: -2px; }
.search-box:not(.drawably-host) .search-input:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.search-input::-webkit-search-cancel-button { -webkit-appearance: none; }

/* ---------- what is inside the drawer ---------- */
.drawer-in form { display: flex; flex-direction: column; padding: .9rem 1.1rem 1.05rem; }
.write-row { will-change: transform, opacity; }
.write-grow { display: flex; flex: 1 1 auto; }

.drawer-in textarea {
  flex: 1 1 auto;
  width: 100%;
  min-height: 7.5rem;
  margin: .55rem 0 .85rem;
  border: 0;
  padding: 0;
  resize: none;
  font-family: var(--hand);
  font-feature-settings: "calt" 1, "rand" 1;
  font-size: clamp(1.4rem, 4vw, 1.85rem);
  line-height: 1.18;
  color: inherit;
  background: transparent;
  outline-offset: 4px;
}
/* The writing surface is the one field that earns a full drawn frame rather
   than a rule: it is where the observation is written, it is a singleton so it
   can afford to boil, and it had no edge and no real focus state at all. The
   frame brings the .drawably-focus layer with it. The margin moves to the
   wrapper, and the padding is restated at two classes to beat the vendor's. */
.text-box {
  display: block;
  flex: 1 1 auto;
  min-width: 0;
  margin: .55rem 0 .85rem;
}
.drawer-in .text-box textarea {
  margin: 0;
  padding: .55rem .75rem;
  resize: none;
}
/* only reachable if the textarea was never framed */
/* was `.write-grow > textarea`, which the .text-box wrapper broke. */
.text-box:not(.drawably-host) textarea:focus-visible { outline: 2px solid var(--accent); }

.tag-input {
  display: block;
  width: 9.5rem;
  margin-left: auto;
  font-family: var(--hand);
  font-size: .82rem;
  font-weight: 500;
  letter-spacing: .16em;
  text-transform: uppercase;
  text-align: right;
  color: inherit;
  background: transparent;
  border: 0;
  padding: 0 0 .3rem;
  /* Was opacity .55, which put 13.12px text at 3.43:1 on paper, and the
     placeholder compounded .55 x .6 for 1.96:1 — the worst number on the page.
     --quiet is the same device .empty and the search placeholder already use,
     ink at 72% over paper and paper at 74% over ink, so it is the palette
     rather than a fifth colour: 5.68:1 light, 8.15:1 dark. The border rides
     currentColor with it, which lifts the rule from 3.43:1 to the same 5.68.
     The rule is drawn now and rides currentColor the same way. */
  color: var(--quiet);
  transition: color .2s ease;
}
.tag-input:focus { color: inherit; }
.tag-input::placeholder { color: var(--quiet); opacity: 1; }

/* These two stay rules rather than becoming boxes. The corner note is a
   swatch's label and the name is a signature; framing either turns the drawer
   into a form, which is a change nobody asked for. An input cannot hold a
   child, so each sits in a wrapper the line is drawn into, and focus is said
   by recolouring and thickening that line rather than by a ring around it. */
.field { position: relative; display: block; padding-bottom: .35rem; }
/* the rule matches its own field: --quiet is the colour the label and the
   placeholder are, and it is what the border-bottom rode before */
.field .hand-rule path { stroke: var(--quiet); }
.field:focus-within .hand-rule path { stroke: var(--accent); }
.field:has(:focus-visible) .hand-rule path { stroke-width: 3.5; }
.tag-field  { width: 9.5rem; margin-left: auto; }
.name-field { flex: 1 1 8.5rem; min-width: 0; }
.tag-field .tag-input  { width: 100%; margin-left: 0; }
.name-field input { flex: none; width: 100%; }
/* only reachable where no line and no frame was drawn */
/* the last two were child combinators the .field wrappers broke. A field
   whose rule was never drawn keeps a real outline; one with a rule does not,
   because the rule thickens and recolours instead. */
.field:not(:has(.hand-rule)):has(:focus-visible),
.field:not(:has(.hand-rule)) input:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

.new-foot {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: .8rem 1rem;
  /* the rule above is an <hr>, drawn; its line sits 5px into a 10px box */
  padding-top: .35rem;
}
.new-by { display: flex; flex-wrap: wrap; gap: .5rem .9rem; flex: 1 1 10rem; min-width: 0; }

.new-by input {
  flex: 1 1 8.5rem;
  min-width: 0;
  font-family: var(--hand);
  font-feature-settings: "calt" 1, "rand" 1;
  font-size: 1.05rem;
  color: inherit;
  background: transparent;
  border: 0;
  padding: 0 0 .3rem;
  /* Same story one field down: opacity .62 was 4.19:1 on paper, failing by a
     hair, and its placeholder compounded to 2.52:1. Same fix, same token. */
  color: var(--quiet);
  transition: color .2s ease;
}
.new-by input:focus { color: inherit; }
.new-by input::placeholder { color: var(--quiet); opacity: 1; }

.new-go { display: flex; align-items: center; gap: .8rem; flex: none; }

/* The refusal message had no rule at all, so it rendered as unstyled 16px
   text in whatever the browser felt like. --on-ground on the page ground is
   13.66:1. The :empty rule means the paragraph can stay in the DOM for
   aria-describedby to point at while it has nothing to say. */
.notice { margin: .7rem 0 0; font-size: 1rem; color: var(--on-ground); }
.notice:empty { display: none; }


/* ---------- buttons ----------
   print it is the one filled button on the page, and its fill is drawn: the
   solid variant paints a rough blob behind the label, so the colour's edge is
   the pen's edge and there is no rectangle under it. Every state is said
   through the custom properties rather than through a background and a border,
   which is also what makes the two themes one set of numbers. */
.btn {
  font-family: var(--hand);
  font-size: 1.05rem;
  font-weight: 500;
  line-height: 1;
  border: 0;   /* same: without this a <button> draws the UA's outset box */
  padding: .55rem 1.1rem .68rem;
  cursor: pointer;
  --drawably-fill:   var(--cobalt);
  --drawably-stroke: var(--cobalt);
  --drawably-paper:  var(--paper);
  color: var(--paper);
}
.btn:hover:not([disabled]) {
  --drawably-fill:   var(--pink);
  --drawably-stroke: var(--pink);
  color: var(--ink);
}
/* A genuinely disabled control is exempt from the contrast rules, so fading it
   is honest. The moment it becomes aria-disabled instead it stops being exempt,
   and the library's own .45 would composite the label down past 2.2:1 against
   its own fill — hence the unfilled treatment below, which says the same thing
   in the four colours and does not need the exemption. The hover swap that
   used to undo itself for a disabled button is gone: hover now excludes
   [disabled] outright, which is one rule instead of three. */
.btn[disabled] { cursor: not-allowed; opacity: 1; }

/* Not yet, rather than off: the plate is simply unfilled until there are
   enough words, which in the library's own vocabulary is a transparent fill
   and an accent edge. Accent on the page ground is 9.83:1 light and 7.23:1
   dark, so the label and the edge both hold at a size where fading would not. */
.btn.is-off,
.btn.is-off:hover {
  --drawably-fill: transparent;
  --drawably-stroke: var(--accent);
  color: var(--accent);
  cursor: not-allowed;
}

/* Cobalt on the dark plate is 1.39:1, so on ink the filled button has no edge
   at all and only its paper label separates it from the page. Pink is the move
   --accent already makes for exactly this reason: 7.23:1 for the edge and
   7.23:1 for the label. */
@media (prefers-color-scheme: dark) {
  .btn {
    --drawably-fill:   var(--pink);
    --drawably-stroke: var(--pink);
    --drawably-paper:  var(--ink);
    color: var(--ink);
  }
  .btn:hover:not([disabled]) {
    --drawably-fill:   var(--cobalt);
    --drawably-stroke: var(--paper);
    color: var(--paper);
  }
}

/* The label is paper on a cobalt fill, so a button whose fill was never drawn
   is paper type on paper. Only reachable in that state. */
.btn:not(.drawably-host) { background: var(--cobalt); border: 1.5px solid var(--cobalt); }
.btn:not(.drawably-host):hover:not([disabled]) { background: var(--pink); border-color: var(--pink); }
.btn:not(.drawably-host).is-off { background: transparent; border-color: var(--accent); }
.btn:not(.drawably-host):focus-visible { outline: 2px solid var(--on-ground); outline-offset: 3px; }
@media (prefers-color-scheme: dark) {
  .btn:not(.drawably-host) { background: var(--pink); border-color: var(--pink); }
  .btn:not(.drawably-host):hover:not([disabled]) { background: var(--cobalt); border-color: var(--paper); }
}


/* ---------- empty ---------- */
.empty {
  font-size: 1.5rem;
  margin: 2rem 0 0;
  color: var(--quiet);
}

/* ---------- toast ---------- */
.toast {
  position: fixed;
  left: 50%; bottom: 1.2rem;
  transform: translateX(-50%) translateY(160%);
  /* the last solid rectangle on the page: a drawn plate now, cobalt filled
     with a paper edge, which is what the 1.5px border used to be. The padding
     pays that border back and gives the deckle its room. */
  --plate: var(--cobalt);
  color: var(--paper);
  font-size: .95rem;
  padding: .6rem 1rem .72rem;
  z-index: 40;
  /* visibility as well as transform: the translate is a percentage of the
     box, and the drawn plate overflows the box, so 160% left a 7px cobalt nub
     pinned to the bottom of every page. Hiding once the slide-out finishes
     costs nothing and does not care how far the deckle sticks out. */
  visibility: hidden;
  transition: transform .28s cubic-bezier(.2, .8, .3, 1), visibility 0s .28s;
  max-width: min(90vw, 32rem);
  pointer-events: none;   /* it says a thing and goes; it never takes a click */
}
.toast.up {
  transform: translateX(-50%) translateY(0);
  visibility: visible;
  transition: transform .28s cubic-bezier(.2, .8, .3, 1), visibility 0s;
}
.toast .hand-fill { stroke: var(--paper); stroke-width: 2.5; }

/* ---------- when nothing drew it ----------
   A plate that was never drawn leaves paper type on paper: an invisible
   masthead, an invisible toast, and on 404.html — which runs no script at all,
   deliberately — an unplated card. These are the only crisp rectangles left in
   the file, and each one is painted only while nothing better exists in its
   place. On this page they are unreachable: hand.js prepends the plate in the
   same task that builds the card, before a frame is painted. */
.band:not(:has(> .hand-plate))  { background: var(--cobalt); }
.toast:not(:has(> .hand-plate)) { background: var(--cobalt); border: 1.5px solid var(--paper); }
.card:not(:has(> .hand-plate))[data-tone="0"] { background: var(--ink); }
.card:not(:has(> .hand-plate))[data-tone="1"] { background: var(--paper); }
.card:not(:has(> .hand-plate))[data-tone="2"] { background: var(--cobalt); }
.card:not(:has(> .hand-plate))[data-tone="3"] { background: var(--pink); }

.visually-hidden {
  position: absolute; width: 1px; height: 1px;
  margin: -1px; padding: 0; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}

/* Durations alone were not the whole of it. The search field fades in on a
   .12s transition delay and the drawer's three rows stagger 60ms apart, so a
   flattened duration still left the waiting. scroll-behavior is here for the
   same reason, even though nothing in this file asks for a smooth scroll yet:
   the day one appears it should already be covered. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    animation-delay: 0s !important;
    transition-duration: .001ms !important;
    transition-delay: 0s !important;
    scroll-behavior: auto !important;
  }
}

@media (max-width: 30rem) {
  /* not the bar — it sets its own height, and this rule comes later */
  /* the same padding the border and the sketch inset were paid back with */
  .card:not(.card-open) { min-height: 18rem; padding: 1.15rem 1.15rem 1.1rem; }
  .wall { padding-bottom: 6rem; }   /* the toast is no smaller on a phone */
  .new-by .name-field,
  .new-by input { flex: 1 1 100%; }   /* room for the whole placeholder */
}
