/* kit.css: design tokens (see DESIGN.md) and vanilla ports of 21st.dev components. */
/* Design tokens. Source of truth: DESIGN.md. Nothing outside these values. */
@font-face { font-family: "Literata"; font-style: normal; font-weight: 200 900; font-display: swap; src: url("fonts/literata-variable.woff2") format("woff2"); }
@font-face { font-family: "Literata"; font-style: italic; font-weight: 200 900; font-display: swap; src: url("fonts/literata-italic-variable.woff2") format("woff2"); }

:root {
  --paper: #EEF0E7; --sheet: #F8F9F3; --ink: #20251F; --lichen: #5A6457; --moss: #3D5C38; --ribbon: #8A3A44;
  --rule: #D5D8CF; --edge: #858881; --wash: #E4E6DD; --moss-wash: #D5DBCE; --ribbon-wash: #E2DAD3;
  --scrim: rgba(32, 37, 31, 0.36);
  --page: var(--sheet);
  --grain: var(--grain-light); --grain-half: var(--grain-light-half); /* tiles are set on the root by the app's script; see DESIGN.md, Paper grain */
  --lift: 0 1px 2px rgba(32, 37, 31, 0.06), 0 12px 32px -8px rgba(32, 37, 31, 0.18);

  --serif: "Literata", "Iowan Old Style", Georgia, serif;
  --sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, system-ui, sans-serif;

  --stroke: 2px; --stroke-h: 0.5rem;
  --s1: 0.25rem; --s2: 0.5rem; --s3: 1rem; --s4: 1.5rem; --s5: 2rem; --s6: 3rem; --s7: 4rem; --s8: 6rem;
  --h-ctl: 2.5rem; --h-tap: 3rem;
  --r-page: 4px; --r-ctl: 8px; --r-sheet: 16px;

  --ease: cubic-bezier(0.23, 1, 0.32, 1);
  --ease-exit: cubic-bezier(0.4, 0, 1, 1);
  --t-fast: 120ms; --t: 200ms;

  --safe-t: env(safe-area-inset-top, 0px); --safe-r: env(safe-area-inset-right, 0px);
  --safe-b: env(safe-area-inset-bottom, 0px); --safe-l: env(safe-area-inset-left, 0px);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --paper: #171916; --sheet: #1F221E; --ink: #E4E6DC; --lichen: #9CA396; --moss: #A6BB97; --ribbon: #D9939A;
    --rule: #30322E; --edge: #6B6D67; --wash: #292C27; --moss-wash: #2B3028; --ribbon-wash: #2E2826;
    --scrim: rgba(0, 0, 0, 0.6);
    --page: var(--paper);
    --grain: var(--grain-dark); --grain-half: var(--grain-dark-half);
    --lift: 0 0 0 1px #30322E;
  }
}
:root[data-theme="dark"] {
  --paper: #171916; --sheet: #1F221E; --ink: #E4E6DC; --lichen: #9CA396; --moss: #A6BB97; --ribbon: #D9939A;
  --rule: #30322E; --edge: #6B6D67; --wash: #292C27; --moss-wash: #2B3028; --ribbon-wash: #2E2826;
  --scrim: rgba(0, 0, 0, 0.6);
  --page: var(--paper);
  --grain: var(--grain-dark); --grain-half: var(--grain-dark-half);
  --lift: 0 0 0 1px #30322E;
}

/* Base */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0; background: var(--paper); background-image: var(--grain); color: var(--ink);
  font-family: var(--sans); font-size: 0.9375rem; line-height: 1.5rem;
  -webkit-font-smoothing: antialiased; font-optical-sizing: auto;
}
button, input, textarea, select { font: inherit; color: inherit; }
button { -webkit-tap-highlight-color: transparent; }
/* The ring shows on keyboard focus. Engines without :focus-visible (iOS 15.0 to 15.3)
   drop the second rule as invalid and keep the ring on every focus. */
:focus { outline: 2px solid var(--moss); outline-offset: 2px; }
:focus:not(:focus-visible) { outline: none; }
.k-vh { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.001ms !important; animation-iteration-count: 1 !important; transition-duration: 0.001ms !important; }
}


/* ===== dialog ===== */
/* kit dialog: alert, confirm and prompt in one panel, plus the button classes
   the whole app uses. Structure, sizes and motion from Modal by ddoemonn
   (21st.dev). Color, type, radius and spacing from DESIGN.md via tokens.css. */

/* ---------------------------------------------------------------- Buttons
   <button class="k-btn">Write</button>
   One button is filled; the rest are words.
   Tone:  (none)      ink fill. The one main action on a screen.
          --quiet     WORD ACTION: moss text in the system face, an optional
                      leading icon (1.25em), no border and no fill at rest,
                      wash behind it on hover and press. The default look for
                      every secondary action. --text is the same thing under
                      its older name.
          --outline   a 1px rule border, ink text. Only where a border carries
                      meaning (a price: ink packs, costumes). Not for actions.
          --danger    ribbon fill, for a destructive confirm. Cancel beside it
                      is a word action.
          --icon      bare ink square (icon only, needs aria-label). Wins over
                      the tones above so an icon-only button stays ink.
   Size:  2.5rem by default, 3rem with --lg and on every coarse pointer.
   Tones are driven by six private properties so any two modifiers combine
   without fighting; when two tones are combined the later one below wins. */
.k-btn {
  --k-btn-bg: var(--ink);
  --k-btn-fg: var(--paper);
  --k-btn-line: transparent;
  --k-btn-bg-on: var(--ink);      /* fill while hovered or pressed */
  --k-btn-line-on: transparent;   /* border while hovered or pressed */
  --k-btn-dim: 0.88;              /* opacity while hovered (filled tones) */

  display: inline-flex; align-items: center; justify-content: center; gap: var(--s2);
  min-height: var(--h-ctl); margin: 0; padding: 0 var(--s3);
  border: 1px solid var(--k-btn-line); border-radius: var(--r-ctl);
  background-color: var(--k-btn-bg); color: var(--k-btn-fg);
  font-family: var(--sans); font-size: 0.9375rem; line-height: 1.5rem; font-weight: 500;
  text-align: center; text-decoration: none; white-space: nowrap;
  cursor: pointer; -webkit-user-select: none; user-select: none;
  -webkit-appearance: none; appearance: none;
  -webkit-tap-highlight-color: transparent; touch-action: manipulation;
  transition: background-color var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease),
              color var(--t-fast) var(--ease), opacity var(--t-fast) var(--ease);
}
.k-btn[hidden] { display: none; }
.k-btn svg { flex: none; width: 1.25em; height: 1.25em; }

/* WORD ACTION. The hook for every secondary action: give a button k-btn--quiet. */
.k-btn--quiet, .k-btn--text {
  --k-btn-bg: transparent; --k-btn-fg: var(--moss); --k-btn-line: transparent;
  --k-btn-bg-on: var(--wash); --k-btn-line-on: transparent; --k-btn-dim: 1;
  padding: 0 var(--s2);
}
.k-btn--outline {
  --k-btn-bg: transparent; --k-btn-fg: var(--ink); --k-btn-line: var(--rule);
  --k-btn-bg-on: var(--wash); --k-btn-line-on: var(--edge); --k-btn-dim: 1;
}
.k-btn--danger {
  --k-btn-bg: var(--ribbon); --k-btn-fg: var(--paper); --k-btn-line: transparent;
  --k-btn-bg-on: var(--ribbon); --k-btn-line-on: transparent; --k-btn-dim: 0.88;
}
.k-btn--icon {
  --k-btn-bg: transparent; --k-btn-fg: var(--ink); --k-btn-line: transparent;
  --k-btn-bg-on: var(--wash); --k-btn-line-on: transparent; --k-btn-dim: 1;
}

.k-btn--lg { min-height: var(--h-tap); padding: 0 var(--s4); }
.k-btn--quiet.k-btn--lg, .k-btn--text.k-btn--lg { padding: 0 var(--s3); }
.k-btn--icon { flex: none; min-width: var(--h-ctl); padding: 0; font-size: 1rem; }
.k-btn--icon.k-btn--lg { min-width: var(--h-tap); }
@media (pointer: coarse) {
  .k-btn { min-height: var(--h-tap); min-width: var(--h-tap); }
  .k-btn--icon { min-width: var(--h-tap); }
}

@media (hover: hover) {
  .k-btn:hover { background-color: var(--k-btn-bg-on); border-color: var(--k-btn-line-on); opacity: var(--k-btn-dim); }
}
.k-btn:active { background-color: var(--k-btn-bg-on); border-color: var(--k-btn-line-on); opacity: 0.76; }
.k-btn:disabled, .k-btn[aria-disabled="true"] { opacity: 0.4; cursor: default; pointer-events: none; }

/* ----------------------------------------------------------------- Dialog
   Built once by dialog.js and appended to <body>:
   .k-dlg > .k-dlg__scrim + .k-dlg__panel > (.k-dlg__content > title, message, input) + .k-dlg__actions
   The overlay is a column. Two empty flex items share the free space around
   the panel: 3 to 1 on phones (the panel rests in the lower third, in reach
   of a thumb), 1 to 1 from 40rem up (centered). --k-dlg-top and
   --k-dlg-bottom are set by the script from the visual viewport so the panel
   stays clear of the on-screen keyboard. The top one adds to the safe area,
   because the status bar still covers the top of a scrolled visual viewport;
   the keyboard already covers the home indicator, so the bottom takes the
   larger of the two. */
.k-dlg {
  position: fixed; top: 0; right: 0; bottom: 0; left: 0;
  z-index: var(--k-z-dialog, 1000);
  display: flex; flex-direction: column; align-items: center;
  padding: calc(var(--s3) + var(--safe-t) + var(--k-dlg-top, 0px))
           calc(var(--s3) + var(--safe-r))
           calc(var(--s3) + max(var(--safe-b), var(--k-dlg-bottom, 0px)))
           calc(var(--s3) + var(--safe-l));
  overscroll-behavior: contain;
}
.k-dlg[hidden] { display: none; }
/* While the scrim fades out the app is live again, so taps pass through. */
.k-dlg[data-state="closed"] { pointer-events: none; }
.k-dlg::before, .k-dlg::after { content: ""; min-height: 0; }
.k-dlg::before { flex: 3 1 0px; }
.k-dlg::after { flex: 1 1 0px; }

.k-dlg__scrim {
  position: absolute; top: 0; right: 0; bottom: 0; left: 0;
  background: var(--scrim); opacity: 0; touch-action: none;
  transition: opacity 150ms var(--ease-exit);
}
.k-dlg[data-state="open"] .k-dlg__scrim { opacity: 1; transition: opacity 200ms var(--ease); }

.k-dlg__panel {
  position: relative; display: flex; flex-direction: column;
  flex: 0 1 auto; min-height: 0; width: 100%; max-width: 27.5rem;
  max-height: 40rem; max-height: min(78vh, 40rem);
  overflow: hidden; border-radius: var(--r-sheet);
  background: var(--sheet); color: var(--ink); box-shadow: var(--lift);
  opacity: 0; transform-origin: 50% 50%;
}
/* The script drives transform with a spring on the way in, so only opacity
   transitions here. On the way out both are plain 150ms transitions. */
.k-dlg__panel[data-state="open"] { opacity: 1; transition: opacity 160ms var(--ease); }
.k-dlg__panel[data-state="closing"] {
  opacity: 0; pointer-events: none;
  transition: opacity 150ms var(--ease-exit), transform 150ms var(--ease-exit);
}

.k-dlg__content {
  flex: 1 1 auto; min-height: 0; padding: var(--s4);
  overflow-y: auto; -webkit-overflow-scrolling: touch; overscroll-behavior: contain;
}
.k-dlg__title {
  margin: 0; color: var(--ink);
  font-family: var(--serif); font-weight: 500; font-size: 1.5rem; line-height: 2rem;
  overflow-wrap: break-word;
}
.k-dlg__message {
  margin: var(--s2) 0 0; color: var(--lichen);
  font-family: var(--sans); font-size: 0.9375rem; line-height: 1.5rem;
  white-space: pre-line; overflow-wrap: break-word;
}
/* With no title the message is the whole statement, so it takes the ink. */
.k-dlg__message--lead { margin-top: 0; color: var(--ink); }

.k-dlg__input {
  display: block; width: 100%; height: var(--h-tap);
  margin: var(--s3) 0 0; padding: 0 var(--s3);
  border: 1px solid var(--edge); border-radius: var(--r-ctl);
  background: var(--page); color: var(--ink); caret-color: var(--moss);
  font-family: var(--sans); font-size: 1rem; font-size: max(16px, 1rem); line-height: 1.5rem;
  -webkit-appearance: none; appearance: none;
}
.k-dlg__input::placeholder { color: var(--lichen); opacity: 1; }
.k-dlg__input:focus { border-color: var(--moss); }
.k-dlg__title[hidden], .k-dlg__message[hidden], .k-dlg__input[hidden] { display: none; }

.k-dlg__actions {
  flex: none; display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end;
  gap: var(--s2); padding: var(--s3) var(--s4);
  border-top: 1px solid var(--rule);
}
/* A long label ("Delete this piece and its drafts") wraps inside its button
   instead of being clipped by the panel. The vertical padding is 0.5rem less
   the 1px border, so one line stays 2.5rem and two lines are 4rem. */
.k-dlg__actions .k-btn {
  min-width: 5rem; max-width: 100%;
  padding-top: calc(var(--s2) - 1px); padding-bottom: calc(var(--s2) - 1px);
  white-space: normal; overflow-wrap: break-word;
}

@media (min-width: 40rem) {
  .k-dlg {
    padding: calc(var(--s4) + var(--safe-t) + var(--k-dlg-top, 0px))
             calc(var(--s4) + var(--safe-r))
             calc(var(--s4) + max(var(--safe-b), var(--k-dlg-bottom, 0px)))
             calc(var(--s4) + var(--safe-l));
  }
  .k-dlg::before { flex-grow: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .k-btn,
  .k-dlg__scrim,
  .k-dlg[data-state="open"] .k-dlg__scrim,
  .k-dlg__panel[data-state="open"],
  .k-dlg__panel[data-state="closing"] { transition: none; }
}


/* ===== stroke ===== */
/* stroke: one drawn mark in moss, an uneven pen line with round caps.
   Brush variant of Text Highlight (uiable, 21st.dev 27942), which draws a
   wavy path 4 units thick in a stretched viewBox. Ported without the scroll
   trigger: the mark is static here, and the segmented control slides it.
   Differences: the thickness is fixed at --stroke through
   vector-effect: non-scaling-stroke (the source's stroke scales with the
   box), there are three hand-uneven paths instead of one regular wave, and
   one is chosen from the label (see Kit.stroke in kit.js).

   <span class="k-stroke-host">Monday</span> + Kit.stroke(host, { label: "Monday" })
   The host needs room under it; the mark sits just below the text. */
.k-stroke-host { position: relative; }
.k-stroke {
  position: absolute; left: 0; bottom: calc(var(--s1) * -2);
  display: block; width: 100%; height: var(--stroke-h);
  overflow: visible; pointer-events: none;
  color: var(--moss);
}
.k-stroke path {
  fill: none; stroke: currentColor; stroke-width: var(--stroke);
  stroke-linecap: round; stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
}
@media (forced-colors: active) { .k-stroke { color: Highlight; } }


/* ===== segmented ===== */
/* segmented: a row of words with a sliding ink stroke.
   The sliding indicator is the underline variant of Animated Tabs
   (educalvolpz, 21st.dev 24930): one mark that moves to the chosen tab and
   takes its width (the source animates a shared layout element with a spring;
   here the same spring as before drives a measured left and width).
   The keyboard model is kept from Segmented Control (ddoemonn, 21st.dev
   23552). The mark is the stroke from the stroke section above. Color, type
   and spacing come from DESIGN.md through the tokens at the top of this file.

   Each option is one real button holding its word. The stroke is one element
   in the grid, positioned from the measured word (left, width, baseline), so
   it stretches to each word's own width. Nothing here draws a box: the
   selected word is ink at weight 500, the others lichen.

   Modifier classes the integrator may put on root:
     k-seg--nav    Literata words for the four places (top bar and bottom bar)
     k-seg--dock   the fixed bottom bar: page ground, hairline above, safe area
   Sizes: md cells 2rem, lg 2.5rem; nav 3rem in the dock. A touch screen gets a
   3rem hit area on every word without changing the layout. */

.k-seg {
  --k-seg-n: 1;                   /* option count, set by Kit.segmented */
  --k-seg-h: 2rem;                /* cell height */
  --k-seg-px: var(--s2);          /* word side padding */
  position: relative;
  isolation: isolate;
  display: inline-block;
  vertical-align: middle;
  max-width: 100%;
  color: var(--lichen);
  font-family: var(--sans);
  font-size: 0.8125rem;
  line-height: 1rem;
  font-weight: 400;
  text-align: center;
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
}
.k-seg--lg { --k-seg-h: 2.5rem; font-size: 0.9375rem; line-height: 1.5rem; }
.k-seg--stretch { display: block; width: 100%; }
/* A row of words that does not stretch hangs its first word's padding into the margin, so that word
   lines up with the text above and below it. */
.k-seg:not(.k-seg--stretch):not(.k-seg--nav) { margin-left: calc(var(--k-seg-px) * -1); }

.k-seg__grid {
  position: relative;
  display: grid;
  /* Equal columns when there is room; a column grows to its word when there is not, so no word is clipped. */
  grid-template-columns: repeat(var(--k-seg-n), minmax(min-content, 1fr));
  min-height: var(--k-seg-h);
  touch-action: manipulation;
}

/* One word. The button is the cell, so the focus ring, the hit area and the
   keyboard all belong to the same element. */
.k-seg__btn {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 0;
  min-height: var(--k-seg-h);
  margin: 0;
  padding: 0 var(--k-seg-px);
  border: 0;
  border-radius: var(--r-ctl);
  background: transparent;
  color: inherit;
  font: inherit;
  white-space: nowrap;
  -webkit-appearance: none;
  appearance: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
  transition: color var(--t) var(--ease);
}
.k-seg__btn[data-on] { color: var(--ink); font-weight: 500; }
.k-seg__btn[aria-disabled="true"] { opacity: 0.5; cursor: default; }
.k-seg__btn:focus-visible { z-index: 1; }

/* The label reserves the width of its heavier, selected form, so the row
   never shifts when the selection moves. A label wider than its column ends
   in an ellipsis. */
.k-seg__text {
  position: relative;
  display: inline-flex;
  flex: none;
  flex-direction: column;
  align-items: center;
  max-width: calc(100% + 2 * var(--k-seg-px));
  pointer-events: none;
}
.k-seg__label { max-width: 100%; overflow: hidden; text-overflow: ellipsis; }
.k-seg__text::after {
  content: attr(data-text);
  max-width: 100%;
  height: 0;
  overflow: hidden;
  visibility: hidden;
  font-weight: 500;
}
.k-seg__icon { display: inline-flex; flex: none; font-size: 1.25em; margin-right: var(--s2); }
.k-seg__icon svg { display: block; width: 1em; height: 1em; }

/* The moving stroke. Left, width and top are written by Kit.segmented. */
.k-seg__ink {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 0;
  width: 0;
  height: var(--stroke-h);
  color: var(--moss);
  pointer-events: none;
  opacity: 1;
  transition: opacity var(--t) var(--ease);
}
.k-seg__ink .k-stroke { position: absolute; top: 0; left: 0; bottom: auto; }
.k-seg[data-empty] .k-seg__ink, .k-seg__ink[data-unmeasured] { opacity: 0; }

/* The four places. Literata, ink on lichen. */
.k-seg--nav { font-family: var(--serif); font-size: 0.9375rem; line-height: 1.5rem; --k-seg-h: 3rem; }
.k-seg--nav .k-seg__btn { padding: 0 var(--s3); }

/* The fixed bottom bar: the page's own ground with a hairline above. */
.k-seg--dock {
  display: block;
  width: 100%;
  background: var(--paper);
  background-image: var(--grain);
  border-top: 1px solid var(--rule);
}
.k-seg--dock .k-seg__btn { padding: 0 var(--s1); }
/* The dock's words touch the left, right and bottom edges of the screen when there is no safe-area inset,
   so an outside ring would be clipped there. The ring is drawn inside the word's box instead. */
.k-seg--dock .k-seg__btn:focus-visible { outline-offset: -2px; }
@supports not selector(:focus-visible) { .k-seg--dock .k-seg__btn:focus { outline-offset: -2px; } }

/* A touched word gets a 3rem hit area even when the word is shorter.
   (hover: none) covers a touch screen that does not report a coarse pointer. */
@media (pointer: coarse), (hover: none) {
  .k-seg__btn::after {
    content: "";
    position: absolute;
    top: 50%;
    right: 0;
    left: 0;
    height: var(--h-tap);
    min-height: 100%;
    transform: translateY(-50%);
  }
}

@media (hover: hover) {
  .k-seg__btn:hover { color: var(--ink); }
}

@media (prefers-reduced-motion: reduce) {
  .k-seg__ink, .k-seg__btn { transition: none; }
}


/* ===== sheet ===== */
/* kit sheet: a bottom sheet under 640px, a centered panel at 640px and up.
   Port of Drawer (wensity, 21st.dev) with the drag rules of BeUI Bottom Sheet.
   Also holds the settings rows (.k-rows, .k-row) and the switch (.k-switch)
   from Preferences Card (ssychui). Color, type and radius come from tokens.css.

   State lives on the root as data-state = closed | opening | open | closing,
   written by sheet.js. "opening" and "closing" are the source's
   data-starting-style and data-ending-style. While a finger is on the handle
   (or the spring is settling) the root carries data-drag and two custom
   properties: --k-sheet-y (panel offset) and --k-sheet-dim (scrim opacity).
   While the on-screen keyboard is up, --k-sheet-kb and --k-sheet-kt are the
   parts of the layout viewport hidden below and above the visible area, so
   the root's content box is what the writer can see. */

/* ---------- Sheet ---------- */

.k-sheet {
  --k-sheet-vh: 85vh;
  position: fixed; top: 0; right: 0; bottom: 0; left: 0; z-index: 100;
  display: flex; align-items: flex-end; justify-content: center;
  padding-top: var(--k-sheet-kt, 0px);
  padding-bottom: var(--k-sheet-kb, 0px);
  touch-action: none;
}
/* dvh is switched on through @supports because a declaration that mixes an
   unknown unit with var() does not fall back on iOS 15, it resets. */
@supports (height: 1dvh) {
  .k-sheet { --k-sheet-vh: 85dvh; }
}
.k-sheet[hidden] { display: none; }

/* Scrim. A click on it lands on the root itself. */
.k-sheet::before {
  content: ""; position: absolute; top: 0; right: 0; bottom: 0; left: 0;
  background: var(--scrim);
  opacity: var(--k-sheet-dim, 1);
  transition: opacity 300ms var(--ease);
}
.k-sheet[data-state="opening"]::before,
.k-sheet[data-state="closing"]::before { opacity: 0; }

.k-sheet__panel {
  position: relative;
  display: flex; flex-direction: column;
  width: 100%;
  max-height: calc(var(--k-sheet-vh) - var(--k-sheet-kb, 0px) - var(--k-sheet-kt, 0px));
  background: var(--sheet); color: var(--ink);
  border-radius: var(--r-sheet) var(--r-sheet) 0 0;
  box-shadow: var(--lift);
  transform: translateY(var(--k-sheet-y, 0px));
  transition: transform 500ms var(--ease);
  will-change: transform;
}
/* A skirt of sheet below the panel, so the rubber-band upward shows no gap. */
.k-sheet__panel::after {
  content: ""; position: absolute; top: 100%; right: 0; left: 0; height: var(--s5);
  background: inherit;
}
.k-sheet[data-state="opening"] .k-sheet__panel,
.k-sheet[data-state="closing"] .k-sheet__panel { transform: translateY(105%); }
.k-sheet[data-state="closing"] .k-sheet__panel { transition-duration: 250ms; }
.k-sheet[data-drag]::before,
.k-sheet[data-drag] .k-sheet__panel { transition: none; }

/* Handle and header are the drag zone. The body below them scrolls. */
.k-sheet__handle {
  flex: 0 0 auto;
  display: flex; justify-content: center; align-items: flex-start;
  height: var(--s3); padding-top: var(--s2);
  touch-action: none; cursor: grab;
}
.k-sheet__handle::before {
  content: ""; width: 2.5rem; height: 0.25rem;
  border-radius: var(--r-page);
  background: var(--lichen); opacity: 0.35;
}

.k-sheet__head {
  flex: 0 0 auto;
  display: grid; grid-template-columns: minmax(0, 1fr) auto; grid-template-rows: minmax(var(--h-tap), auto);
  align-items: center; column-gap: var(--s3);
  padding: 0 var(--s2) var(--s2) var(--s4);
  border-bottom: 1px solid var(--rule);
  touch-action: none; cursor: grab;
  -webkit-user-select: none; user-select: none;
}
.k-sheet__panel > .k-sheet__head:first-child { padding-top: var(--s2); }
.k-sheet__head h2,
.k-sheet__title {
  grid-column: 1; grid-row: 1;
  margin: 0;
  font-family: var(--serif); font-weight: 500; font-size: 1.5rem; line-height: 2rem;
  overflow-wrap: break-word;
}
.k-sheet__desc {
  grid-column: 1 / -1; grid-row: 2;
  margin: 0; padding-right: var(--s3);
  font-size: 0.8125rem; line-height: 1rem; color: var(--lichen);
}
.k-sheet[data-drag] .k-sheet__handle,
.k-sheet[data-drag] .k-sheet__head { cursor: grabbing; }
.k-sheet[data-dismissible="false"] .k-sheet__handle,
.k-sheet[data-dismissible="false"] .k-sheet__head { cursor: auto; }
.k-sheet[data-dismissible="false"] .k-sheet__handle::before { opacity: 0; }

.k-sheet__close {
  grid-column: 2; grid-row: 1;
  display: inline-flex; align-items: center; justify-content: center;
  width: var(--h-tap); height: var(--h-tap);
  margin: 0; padding: 0; border: 0;
  border-radius: var(--r-ctl);
  background: none; color: var(--lichen);
  font-size: 1.5rem; line-height: 1;
  cursor: pointer;
  transition: background-color var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}
.k-sheet__close svg { display: block; width: 1em; height: 1em; }
.k-sheet__close:active { background: var(--wash); color: var(--ink); }
@media (hover: hover) {
  .k-sheet__close:hover { background: var(--wash); color: var(--ink); }
}

.k-sheet__body {
  flex: 1 1 auto; min-height: 0;
  overflow-x: hidden; overflow-y: auto;
  -webkit-overflow-scrolling: touch; overscroll-behavior: contain;
  touch-action: pan-y;
  padding: var(--s3) var(--s4) calc(var(--s4) + var(--safe-b));
}

/* Optional footer for the sheet's own actions. It takes over the safe area. */
.k-sheet__foot {
  flex: 0 0 auto;
  display: flex; align-items: center; justify-content: flex-end; gap: var(--s2);
  padding: var(--s3) var(--s4) calc(var(--s3) + var(--safe-b));
  border-top: 1px solid var(--rule);
}
.k-sheet__panel[data-foot] .k-sheet__body { padding-bottom: var(--s4); }

/* 640px and up: a centered panel. No handle, no drag. */
@media (min-width: 640px) {
  .k-sheet {
    align-items: center;
    padding:
      calc(var(--s4) + var(--safe-t) + var(--k-sheet-kt, 0px))
      calc(var(--s4) + var(--safe-r))
      calc(var(--s4) + var(--safe-b) + var(--k-sheet-kb, 0px))
      calc(var(--s4) + var(--safe-l));
  }
  .k-sheet__panel {
    max-width: 34rem;
    max-height: min(var(--k-sheet-vh), 100%);
    border-radius: var(--r-sheet);
    opacity: 1; transform: none;
    transition: opacity 500ms var(--ease), transform 500ms var(--ease);
  }
  .k-sheet--sm .k-sheet__panel { max-width: 26rem; }
  .k-sheet--lg .k-sheet__panel { max-width: 44rem; }
  /* 12px is the rise named in the motion spec. */
  .k-sheet[data-state="opening"] .k-sheet__panel,
  .k-sheet[data-state="closing"] .k-sheet__panel { opacity: 0; transform: translateY(12px) scale(0.96); }
  .k-sheet__handle,
  .k-sheet__panel::after { display: none; }
  .k-sheet__head {
    padding-top: var(--s2);
    touch-action: auto; cursor: auto;
    -webkit-user-select: text; user-select: text;
  }
  .k-sheet__body { padding-bottom: var(--s4); }
  .k-sheet__foot { padding-bottom: var(--s3); }
}

/* ---------- Rows (settings style lists, inside a sheet or on a page) ---------- */

.k-rows { min-width: 0; margin: 0; padding: 0; border: 0; list-style: none; }
.k-rows + .k-rows { margin-top: var(--s4); }
.k-rows__title {
  margin: 0; padding: var(--s2) 0;
  font-family: var(--sans); font-size: 0.8125rem; line-height: 1rem; font-weight: 500;
  color: var(--lichen);
}

.k-row {
  display: flex; align-items: center; justify-content: space-between; gap: var(--s3);
  width: 100%; min-height: 3.5rem;
  margin: 0; padding: var(--s2) 0;
  border: 0 solid var(--rule);
  font-family: var(--sans); font-size: 0.9375rem; line-height: 1.5rem; font-weight: 400;
  color: var(--ink); text-align: start;
}
.k-row + .k-row { border-top-width: 1px; }
label.k-row { cursor: pointer; }

.k-row__text { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; overflow-wrap: break-word; }
.k-row__label { display: block; }
.k-row__desc { display: block; font-size: 0.8125rem; line-height: 1rem; color: var(--lichen); }
.k-row__ctl {
  flex: 0 0 auto;
  display: flex; align-items: center; gap: var(--s2);
  margin: calc(var(--s1) * -1) 0;
}
.k-row__value {
  flex: 0 0 auto;
  color: var(--lichen); white-space: nowrap; font-variant-numeric: tabular-nums;
}
.k-row__chev {
  flex: 0 0 auto; display: block;
  width: 1em; height: 1em; margin-right: calc(var(--s2) * -1);
  font-size: 1.5rem; color: var(--lichen);
}

/* The whole row is a button or a link. */
.k-row--link {
  position: relative; isolation: isolate;
  border-radius: 0; background: none;
  -webkit-appearance: none; appearance: none;
  text-decoration: none; cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.k-row--link::before {
  content: ""; position: absolute; z-index: -1;
  top: 0; bottom: 0; left: calc(var(--s2) * -1); right: calc(var(--s2) * -1);
  border-radius: var(--r-ctl);
  background: var(--wash); opacity: 0;
  transition: opacity var(--t-fast) var(--ease);
}
.k-row--link:active::before { opacity: 1; }
.k-row--link:active .k-row__chev { color: var(--ink); }
@media (hover: hover) {
  .k-row--link:hover::before { opacity: 1; }
  .k-row--link:hover .k-row__chev { color: var(--ink); }
}

/* ---------- Switch ---------- */
/* <label class="k-switch"><input type="checkbox" role="switch"><span class="k-switch__track"></span></label>
   Inside a <label class="k-row"> use a <span class="k-switch"> so labels do not nest. */

.k-switch {
  position: relative; flex: 0 0 auto;
  display: inline-flex; align-items: center; justify-content: center;
  min-width: var(--h-tap); min-height: var(--h-tap);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.k-row .k-switch { justify-content: flex-end; margin: calc(var(--s2) * -1) 0; }
.k-switch input {
  position: absolute; top: 0; left: 0;
  width: 100%; height: 100%; margin: 0;
  opacity: 0; cursor: inherit;
  -webkit-appearance: none; appearance: none;
}
/* --r-sheet is larger than half the track height, so it renders as a full pill. */
.k-switch__track {
  position: relative; display: block;
  width: 2.5rem; height: 1.5rem;
  border-radius: var(--r-sheet);
  background: var(--edge);
  transition: background-color var(--t) var(--ease);
}
.k-switch__track::after {
  content: ""; position: absolute; top: 0.25rem; left: 0.25rem;
  width: 1rem; height: 1rem;
  border-radius: 50%;
  background: var(--sheet);
  transition: transform var(--t) var(--ease);
}
.k-switch input:checked + .k-switch__track { background: var(--moss); }
.k-switch input:checked + .k-switch__track::after { transform: translateX(1rem); }
/* The input is invisible, so the same global ring is drawn on the track. */
.k-switch input:focus-visible + .k-switch__track { outline: 2px solid var(--moss); outline-offset: 2px; }
.k-switch input:disabled { cursor: default; }
.k-switch input:disabled + .k-switch__track { opacity: 0.5; }

/* ---------- Reduced motion: every state change is instant ---------- */
@media (prefers-reduced-motion: reduce) {
  .k-sheet::before,
  .k-sheet__panel,
  .k-sheet__close,
  .k-row--link::before,
  .k-switch__track,
  .k-switch__track::after { transition: none; }
  .k-sheet[data-state="opening"] .k-sheet__panel,
  .k-sheet[data-state="closing"] .k-sheet__panel { transform: none; }
}


/* ===== menu ===== */
/* kit menu: dropdown / popover menu for secondary actions.
   Port of Dropdown by ddoemonn (21st.dev 23528) with the menu roles and
   fixed, edge-aware placement of the same author's Context Menu (23560).
   Structure, sizes and motion from the source; color, type and radius from
   DESIGN.md. Needs tokens.css. Behaviour lives in menu.js. */

/* Panel. Built by menu.js, appended to <body>, placed with left / top.
   Stacking: above the Writer (60) and sheets (100) a menu can open from,
   below the palette (700), dialogs (1000), the lock (2000) and toasts, so a
   confirm opened from a row covers the menu while it fades out. */
.k-menu {
  --k-menu-row: 2.5rem;
  --k-menu-hl: var(--wash);
  position: fixed;
  top: 0;
  left: 0;
  z-index: var(--k-z-menu, 600);
  width: max-content;
  min-width: 12rem;
  max-width: calc(100vw - 1rem);
  max-height: calc(100vh - 1rem);
  margin: 0;
  padding: var(--s2);
  overflow-x: hidden;
  overflow-y: auto;
  background: var(--sheet);
  color: var(--ink);
  border-radius: var(--r-ctl);
  box-shadow: var(--lift);
  font-family: var(--sans);
  font-size: 0.9375rem;
  line-height: 1.5rem;
  font-weight: 400;
  text-align: left;
  text-align: start;
  white-space: nowrap;
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
  opacity: 0;
  transition: opacity var(--t-fast) var(--ease);
  /* Not layout. menu.js reads these four back as pixels so the panel stays
     clear of the notch and the home bar. A fixed element never uses them. */
  scroll-margin: var(--safe-t) var(--safe-r) var(--safe-b) var(--safe-l);
}
.k-menu[data-state="open"] { opacity: 1; }
.k-menu[data-state="closing"] {
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--t-fast) var(--ease-exit), transform var(--t-fast) var(--ease-exit);
}

/* Wash is ink on paper, which disappears against the sheet tone in Ink, so
   the highlight steps up to the rule tint there. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .k-menu { --k-menu-hl: var(--rule); }
}
:root[data-theme="dark"] .k-menu { --k-menu-hl: var(--rule); }

@media (pointer: coarse) {
  .k-menu { --k-menu-row: 3rem; }
}

/* The highlight that slides between rows. menu.js sets its height and
   translateY from the active row; it stays at opacity 0 when nothing is
   active so it fades in where it is needed. */
.k-menu-hl {
  position: absolute;
  top: 0;
  left: var(--s2);
  right: var(--s2);
  height: var(--k-menu-row);
  border-radius: var(--r-page);
  background-color: var(--k-menu-hl);
  opacity: 0;
  pointer-events: none;
  transition: opacity 100ms var(--ease), background-color 100ms var(--ease);
}
.k-menu-hl--on { opacity: 1; }
.k-menu-hl--danger { background-color: var(--ribbon-wash); }

/* Rows. Real buttons; position: relative keeps their text above the highlight. */
.k-menu-item {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--s2);
  width: 100%;
  height: var(--k-menu-row);
  margin: 0;
  padding: 0 var(--s2);
  border: 0;
  border-radius: var(--r-page);
  background: none;
  -webkit-appearance: none;
  appearance: none;
  color: var(--ink);
  font: inherit;
  text-align: left;
  text-align: start;
  white-space: nowrap;
  cursor: default;
  touch-action: manipulation;
  scroll-margin: var(--s2) 0;
}
.k-menu-item--danger { color: var(--ribbon); }
.k-menu-item[aria-disabled="true"] { color: var(--lichen); opacity: 0.7; }

.k-menu-label {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}
.k-menu-hint {
  flex: none;
  margin-left: var(--s2);
  margin-inline-start: var(--s2);
  margin-inline-end: 0;
  color: var(--lichen);
  font-size: 0.8125rem;
  line-height: 1rem;
  font-variant-numeric: tabular-nums;
}

.k-menu-icon,
.k-menu-check {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.125em;
  height: 1.125em;
}
.k-menu-icon { color: var(--lichen); }
.k-menu-item--danger .k-menu-icon { color: inherit; }
.k-menu-check { color: var(--moss); }
.k-menu-icon svg,
.k-menu-check svg { display: block; width: 100%; height: 100%; }

/* Hairline between sections, bled to the panel edge. */
.k-menu-sep {
  height: 1px;
  margin: var(--s2) calc(var(--s2) * -1);
  background: var(--rule);
}

.k-menu-heading {
  padding: var(--s2);
  overflow: hidden;
  text-overflow: ellipsis;
  color: var(--lichen);
  font-size: 0.8125rem;
  line-height: 1rem;
  font-weight: 500;
}

/* Optional trigger styling. Kit.menu works with any <button>; these classes
   give a quiet text or icon button, a 3rem hit area on touch, and the
   source's chevron that turns over while the menu is open. */
.k-menu-trigger {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s2);
  height: var(--h-ctl);
  min-width: var(--h-ctl);
  margin: 0;
  padding: 0 var(--s3);
  border: 0;
  border-radius: var(--r-ctl);
  background-color: transparent;
  -webkit-appearance: none;
  appearance: none;
  color: var(--ink);
  font-family: var(--sans);
  font-size: 0.9375rem;
  line-height: 1.5rem;
  font-weight: 500;
  white-space: nowrap;
  cursor: pointer;
  touch-action: manipulation;
  transition: background-color 150ms var(--ease);
}
.k-menu-trigger--icon { width: var(--h-ctl); padding: 0; }
.k-menu-trigger[aria-expanded="true"] { background-color: var(--wash); }
.k-menu-trigger svg { flex: none; width: 1.25em; height: 1.25em; }
.k-menu-trigger .k-menu-chev {
  width: 1em;
  height: 1em;
  color: var(--lichen);
  transition: transform 220ms var(--ease);
}
.k-menu-trigger[aria-expanded="true"] .k-menu-chev { transform: rotate(180deg); }

@media (hover: hover) {
  .k-menu-trigger:hover { background-color: var(--wash); }
}
@media (pointer: coarse) {
  .k-menu-trigger { height: var(--h-tap); min-width: var(--h-tap); }
  .k-menu-trigger--icon { width: var(--h-tap); }
}


/* ===== toast ===== */
/* Toast: quiet confirmations of discrete actions ("Kept", "Copied",
   "Swapped" with Undo). Port of Toast by shugar (21st.dev). Structure, stack
   offsets and the 350ms curve come from the source; color, type and radius
   come from DESIGN.md. Needs tokens.css first. Positions, heights and stack
   transforms are written inline by toast.js. */

.k-toast-region {
  --k-toast-ease: cubic-bezier(.25, .75, .6, .98); /* the source's one curve */
  --k-toast-time: 350ms;
  position: fixed;
  /* above sheet 100, menu 600, palette 700, dialog 1000. --k-z-toast matches
     the siblings' --k-z-menu / --k-z-dialog names; --k-toast-z still works. */
  z-index: var(--k-z-toast, var(--k-toast-z, 1100));
  left: calc(var(--safe-l) + 1rem);
  right: calc(var(--safe-r) + 1rem);
  bottom: calc(var(--k-toast-bottom, 1rem) + var(--safe-b));
  max-width: 26rem;
  height: 0;
  margin: 0 auto;
  pointer-events: none;
  font-family: var(--sans);
  font-size: 0.9375rem;
  line-height: 1.5rem;
}
/* While it holds toasts the region is the hit area for the whole stack, so
   the gaps of an opened stack do not count as leaving it. */
.k-toast-region--open { pointer-events: auto; }

.k-toast-item {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  overflow: hidden;
  border-radius: var(--r-ctl);
  background-color: var(--ink);
  color: var(--paper);
  box-shadow: var(--lift);
  transform-origin: 50% 0;
  touch-action: none;
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
  transition:
    transform var(--k-toast-time) var(--k-toast-ease),
    opacity var(--k-toast-time) var(--k-toast-ease),
    max-height var(--k-toast-time) var(--k-toast-ease),
    background-color var(--k-toast-time) var(--k-toast-ease);
}
/* A toast waiting behind the front one (only one that carries a control ever
   waits; see kit.js) steps back in tone as well as size, so its edge reads on
   both themes (an ink slab on an ink slab would not). All that wait share the
   one step, so a single edge shows. */
.k-toast-item[data-depth="1"] { background-color: var(--lichen); }
.k-toast-item[data-depth="2"],
.k-toast-item[data-depth="3"] { background-color: var(--edge); }

.k-toast-item--drag { transition: none; }
.k-toast-item--leaving { pointer-events: none; }

.k-toast-body {
  display: flex;
  align-items: center;
  gap: var(--s3);
  min-height: var(--h-tap);
  padding: var(--s2) var(--s3);
  transition: opacity var(--k-toast-time) var(--k-toast-ease);
}
.k-toast-body--action { padding-right: var(--s2); }
/* A row of its own under the words, for a small control the message asks about. */
.k-toast-body--extra { flex-wrap: wrap; row-gap: 0; }
.k-toast-extra { flex: 1 0 100%; min-width: 0; }
.k-toast-item:not([data-depth="0"]) .k-toast-body { opacity: 0; pointer-events: none; }

.k-toast-msg {
  flex: 1 1 auto;
  min-width: 0;
  overflow-wrap: break-word;
}

/* The action: paper text, underlined, weight 500. The box is 2rem tall so
   the global focus ring fits inside the toast; ::after carries the 3rem hit
   area out to the toast's edges. */
.k-toast-action {
  position: relative;
  z-index: 0;
  flex: none;
  min-width: var(--s5);
  max-width: 50%; /* a long label wraps instead of pushing out of the toast */
  min-height: var(--s5);
  margin: 0;
  padding: 0 var(--s2);
  border: 0;
  border-radius: var(--r-page);
  background: transparent;
  color: inherit;
  font-weight: 500;
  text-decoration: underline;
  text-underline-offset: 0.25rem;
  cursor: pointer;
}
/* A paper plate under the focused action. The moss ring from tokens.css is
   untouched; it would be hard to see straight on the ink surface, so the
   plate gives it paper to sit on. */
.k-toast-action::before {
  content: "";
  position: absolute;
  z-index: -1;
  top: -0.25rem;
  right: -0.25rem;
  bottom: -0.25rem;
  left: -0.25rem;
  border-radius: var(--r-ctl);
  background: var(--paper);
  opacity: 0;
}
.k-toast-action::after {
  content: "";
  position: absolute;
  top: -0.5rem;
  right: -0.5rem;
  bottom: -0.5rem;
  left: -0.5rem;
}
.k-toast-action:focus-visible { color: var(--ink); }
.k-toast-action:focus-visible::before { opacity: 1; }
/* iOS 15.0 to 15.3 has no :focus-visible; show the plate on plain focus. */
@supports not selector(:focus-visible) {
  .k-toast-action:focus { color: var(--ink); }
  .k-toast-action:focus::before { opacity: 1; }
}
.k-toast-action:active { opacity: 0.7; }

@media (hover: hover) {
  .k-toast-action:hover { text-decoration-thickness: 2px; }
}

@media (prefers-reduced-motion: reduce) {
  .k-toast-item,
  .k-toast-body { transition: none; }
}


/* ===== palette ===== */
/* Command palette. Vanilla port of Command Palette (ddoemonn, 21st.dev 23522)
   with grouped results from Command Search (arihantcodes, 21st.dev 28888).
   Needs tokens.css. Layout is phone first (full screen); 640px and up is the
   floating panel. Driven by palette.js through data-state on .k-pal:
   closed (hidden), open, closing. */

.k-pal {
  position: fixed; top: 0; right: 0; bottom: 0; left: 0;
  z-index: var(--k-z-palette, 700);
  font-family: var(--sans); font-size: 0.9375rem; line-height: 1.5rem;
  color: var(--ink);
}
.k-pal[hidden] { display: none; }
/* During the exit the panel is dead to the pointer, but the scrim still
   catches stray clicks (the second click of a double-click on a row) so
   they never reach what the chosen item opened underneath. */
.k-pal[data-state="closing"] .k-pal-panel { pointer-events: none; }

/* Scrim: 200ms in, 150ms out (source LAYER_EASE and LAYER_OUT). */
.k-pal-scrim {
  position: absolute; top: 0; right: 0; bottom: 0; left: 0;
  background: var(--scrim);
  opacity: 0;
  transition: opacity var(--t) var(--ease);
}
.k-pal[data-state="open"] .k-pal-scrim { opacity: 1; }
.k-pal[data-state="closing"] .k-pal-scrim { opacity: 0; transition: opacity 150ms var(--ease-exit); }

/* Panel. Phone: fills the visible viewport from the top. palette.js keeps
   --k-pal-vh and --k-pal-vt in step with visualViewport so the list ends
   above the keyboard; without them it is simply full height. */
.k-pal-panel {
  position: absolute; top: var(--k-pal-vt, 0px); left: 0; right: 0;
  height: var(--k-pal-vh, 100%);
  display: flex; flex-direction: column;
  padding: var(--safe-t) var(--safe-r) 0 var(--safe-l);
  background: var(--sheet);
  opacity: 0;
  transition: opacity var(--t) var(--ease);
}
.k-pal[data-state="open"] .k-pal-panel { opacity: 1; }
.k-pal[data-state="closing"] .k-pal-panel {
  opacity: 0;
  transition: opacity 150ms var(--ease-exit), transform 150ms var(--ease-exit);
}

/* Input row: 3.5rem, search icon, input, Close. */
.k-pal-head {
  flex: none;
  display: flex; align-items: center; gap: var(--s2);
  height: 3.5rem;
  padding: 0 var(--s2) 0 var(--s3);
  border-bottom: 1px solid var(--rule);
}
.k-pal-search {
  flex: none;
  display: flex; align-items: center; justify-content: center;
  width: var(--s4); height: var(--s4);
  font-size: 1rem;
  color: var(--lichen);
}
.k-pal-search svg, .k-pal-ico svg { display: block; width: 1.25em; height: 1.25em; }

.k-pal-input {
  flex: 1 1 auto; min-width: 0;
  height: 100%;
  margin: 0; padding: 0;
  border: 0; border-radius: 0;
  background: transparent;
  color: var(--ink);
  font-family: var(--sans);
  font-size: 16px; font-size: max(16px, 1rem);
  line-height: 1.5rem;
  caret-color: var(--moss);
  -webkit-appearance: none; appearance: none;
}
/* The brief: no outline on the input. Focus shows through the caret, and the
   active row carries a fill and a margin bar instead. */
/* Two rules, not one list: iOS 15.0 to 15.3 lack :focus-visible and would
   drop a combined selector whole. */
.k-pal-input:focus { outline: none; }
.k-pal-input:focus-visible { outline: none; }
.k-pal-input::placeholder { color: var(--lichen); opacity: 1; }

.k-pal-close {
  flex: none;
  display: inline-flex; align-items: center; justify-content: center;
  min-width: var(--h-tap); height: var(--h-tap);
  margin: 0; padding: 0 var(--s2);
  border: 0; border-radius: var(--r-ctl);
  background: transparent;
  color: var(--ink);
  font-family: var(--sans); font-size: 0.9375rem; line-height: 1.5rem; font-weight: 500;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.k-pal-close:active { background: var(--wash); }
@media (hover: hover) {
  .k-pal-close:hover { background: var(--wash); }
}

/* Results. The list is the scroll container; options never take focus. */
.k-pal-list {
  position: relative;
  flex: 1 1 auto; min-height: 0;
  overflow-x: hidden; overflow-y: auto;
  overscroll-behavior: contain;
  padding: 0 var(--s2) calc(var(--s2) + var(--safe-b));
}
.k-pal-list[hidden], .k-pal-empty[hidden] { display: none; }

.k-pal-group + .k-pal-group { margin-top: var(--s2); }
/* A first group with no heading would sit flush on the input rule. */
.k-pal-group:first-child > .k-pal-opt:first-child { margin-top: var(--s2); }
.k-pal-heading {
  padding: var(--s3) var(--s2) var(--s2);
  font-size: 0.8125rem; line-height: 1rem; font-weight: 500;
  overflow-wrap: break-word;
  color: var(--lichen);
}

.k-pal-opt {
  position: relative; z-index: 0;
  display: flex; align-items: center; gap: var(--s2);
  min-height: var(--h-tap);
  padding: var(--s2);
  border-radius: var(--r-ctl);
  cursor: default;
  -webkit-tap-highlight-color: transparent;
  -webkit-user-select: none; user-select: none;
}
/* Active row: a moss-wash fill plus a moss bar in the left margin (shape,
   not only color). Both crossfade with the source CROSSFADE spring
   (stiffness 260, damping 34, mass 0.8), fitted to 500ms on this curve. */
.k-pal-opt::before, .k-pal-opt::after {
  content: "";
  position: absolute;
  opacity: 0;
  transition: opacity 500ms cubic-bezier(0.25, 0.4, 0.15, 1);
}
.k-pal-opt::before {
  z-index: -1;
  top: 0; right: 0; bottom: 0; left: 0;
  border-radius: var(--r-ctl);
  background: var(--moss-wash);
}
/* The bar is a border, not a background, so it survives forced-colors
   mode, where backgrounds are flattened and the fill would vanish. */
.k-pal-opt::after {
  top: var(--s2); bottom: var(--s2); left: 0;
  border-left: var(--s1) solid var(--moss);
}
.k-pal-opt[aria-selected="true"]::before, .k-pal-opt[aria-selected="true"]::after { opacity: 1; }

.k-pal-ico {
  flex: none;
  display: flex; align-items: center; justify-content: center;
  width: var(--s4); height: var(--s4);
  font-size: 1rem;
  color: var(--lichen);
}

.k-pal-text { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
.k-pal-label {
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2;
  overflow: hidden;
  overflow-wrap: break-word;
  font-size: 0.9375rem; line-height: 1.5rem;
  color: var(--ink);
}
.k-pal-snip {
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2;
  overflow: hidden;
  overflow-wrap: break-word;
  font-size: 0.8125rem; line-height: 1rem;
  color: var(--lichen);
}
.k-pal-sub {
  overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
  font-size: 0.8125rem; line-height: 1rem;
  color: var(--lichen);
}
.k-pal-hint {
  flex: 0 1 auto; max-width: 40%;
  overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
  font-size: 0.8125rem; line-height: 1rem;
  font-variant-numeric: tabular-nums;
  color: var(--lichen);
}
/* The match: weight and a moss underline, so it reads on the plain and the
   active row alike. */
.k-pal-mark {
  background: transparent;
  color: var(--ink);
  font-weight: 500;
  text-decoration: underline;
  text-decoration-color: var(--moss);
  text-underline-offset: 0.15em;
}
/* Lichen on moss-wash is 4.4:1 in Paper, so secondary text darkens on the
   active row (source: label color transition, 150ms). */
.k-pal-ico, .k-pal-snip, .k-pal-sub, .k-pal-hint { transition: color 150ms var(--ease); }
.k-pal-opt[aria-selected="true"] .k-pal-ico,
.k-pal-opt[aria-selected="true"] .k-pal-snip,
.k-pal-opt[aria-selected="true"] .k-pal-sub,
.k-pal-opt[aria-selected="true"] .k-pal-hint { color: var(--ink); }

.k-pal-empty {
  margin: 0;
  padding: var(--s4) var(--s3) calc(var(--s4) + var(--safe-b));
  font-size: 0.9375rem; line-height: 1.5rem;
  /* The default text quotes the query; a pasted link or a long run of
     letters must wrap, not run off the panel. */
  overflow-wrap: break-word;
  color: var(--lichen);
  animation: k-pal-in 500ms cubic-bezier(0.25, 0.4, 0.15, 1) both;
}
@keyframes k-pal-in { from { opacity: 0; } to { opacity: 1; } }

/* 640px and up: a floating panel, top at 12vh. palette.js springs its
   transform in (420 / 36 / 0.9); opacity runs 160ms as in the source. */
@media (min-width: 640px) {
  .k-pal {
    display: flex; justify-content: center; align-items: flex-start;
    padding: 12vh var(--s3) var(--s3);
  }
  .k-pal-panel {
    position: relative; top: auto; left: auto; right: auto;
    width: 100%; max-width: 35rem; height: auto;
    padding: 0;
    border-radius: var(--r-sheet);
    box-shadow: var(--lift);
    transition-duration: 160ms;
  }
  /* The list clips its own rows to the panel's lower corners, so the panel
     needs no overflow clip and the Close focus ring is never cut. */
  .k-pal-list {
    flex: 0 1 auto;
    max-height: min(60vh, 28rem);
    max-height: min(60vh, 28rem, calc(var(--k-pal-vh, 100vh) - 12vh - 4.5rem));
    padding-bottom: var(--s2);
    border-radius: 0 0 var(--r-sheet) var(--r-sheet);
  }
  .k-pal-empty { padding-bottom: var(--s4); }
  .k-pal-close { display: none; }
}
/* Tablets and touch screens at 640px and up keep the Close button. */
@media (min-width: 640px) and (hover: none), (min-width: 640px) and (pointer: coarse) {
  .k-pal-close { display: inline-flex; }
}

@media (prefers-reduced-motion: reduce) {
  .k-pal-scrim, .k-pal-panel, .k-pal[data-state="closing"] .k-pal-scrim, .k-pal[data-state="closing"] .k-pal-panel,
  .k-pal-opt::before, .k-pal-opt::after, .k-pal-ico, .k-pal-snip, .k-pal-sub, .k-pal-hint { transition: none; }
  .k-pal-empty { animation: none; }
}


/* ===== text ===== */
/* kit text: growing textarea, progress ring and bar. The ink settle (Kit.settle) is
   a Web Animations call and needs no CSS. Needs tokens.css. Sources on 21st.dev:
   useAutoResizeTextarea (kokonutd), Circle Progress (hihahihahoho),
   Progress Bar (ddoemonn). Color, type and radius come from DESIGN.md. */

/* Growing textarea. Kit.autogrow adds .k-tx-grow; the height is set inline
   from scrollHeight, so there is never an inner scrollbar and no drag handle
   to fight it. No height transition: it would lag behind the caret. */
.k-tx-grow {
  resize: none;
  overflow: hidden;
}

/* Optional writing surface in the "writing" role of the type scale. The
   padding gives the focus ring room and lets a tap beside the text land in
   the field. */
.k-tx-area {
  display: block;
  width: 100%;
  min-width: 0;
  margin: 0;
  padding: var(--s3);
  border: 0;
  border-radius: var(--r-ctl);
  background: transparent;
  color: var(--ink);
  font-family: var(--serif);
  font-weight: 400;
  font-size: 1.1875rem;
  line-height: 2rem;
  -webkit-appearance: none;
  appearance: none;
}
.k-tx-area::placeholder { color: var(--lichen); opacity: 1; }
@media (min-width: 640px) {
  .k-tx-area { font-size: 1.3125rem; line-height: 2.25rem; }
}

/* Ring. Kit.ring sets --k-tx-ring (the size in rem) and draws two circles.
   An empty ring hides its arc, because a round line cap would leave a dot at
   twelve o'clock; the hide waits for the arc to finish draining. */
.k-tx-ring {
  display: inline-block;
  flex: none;
  width: var(--k-tx-ring, 1.5rem);
  height: var(--k-tx-ring, 1.5rem);
  line-height: 0;
  vertical-align: middle;
}
.k-tx-ring svg { display: block; width: 100%; height: 100%; }
.k-tx-ring-track { fill: none; stroke: var(--rule); }
.k-tx-ring-fill {
  fill: none;
  stroke: var(--moss);
  stroke-linecap: round;
  transition: stroke-dashoffset 300ms var(--ease), visibility 0s linear 0s;
}
.k-tx-ring[data-empty] .k-tx-ring-fill {
  visibility: hidden;
  transition: stroke-dashoffset 300ms var(--ease), visibility 0s linear 300ms;
}

/* Bar. A 2px rule that fills from the left. The track clips and carries the
   radius; the fill only scales, so typing never causes layout work. */
.k-tx-bar {
  display: block;
  width: 100%;
  height: 2px;
  border-radius: var(--r-page);
  background: var(--rule);
  overflow: hidden;
}
.k-tx-bar-fill {
  display: block;
  width: 100%;
  height: 100%;
  background: var(--lichen);
  transform: scaleX(0);
  transform-origin: 0 50%;
  transition: transform 300ms var(--ease), background-color 300ms var(--ease);
}
.k-tx-bar[data-met] .k-tx-bar-fill { background: var(--moss); }

/* Reduced motion: the base rule in tokens.css shortens durations but keeps
   delays, so the transitions are switched off outright here. */
@media (prefers-reduced-motion: reduce) {
  .k-tx-ring-fill,
  .k-tx-ring[data-empty] .k-tx-ring-fill,
  .k-tx-bar-fill { transition: none; }
}


/* ===== heat ===== */
/* kit heat: three small pieces for data and long lists.
   1. .k-heat          the calendar of days written (Kit.heat). Weeks are columns,
                       days are rows, one hue in five steps.
   2. .k-heat-figures  a plain line of figures to sit above the calendar (CSS only).
   3. .k-heat-glide    the wash that glides between rows of an index (Kit.glide).
   Structure, sizes and motion numbers: Heat Calendar (ssychui), Heat Strip numbers
   row (eugeneshilow), Table with proximity hover (micka_design).
   Color, type and radius: DESIGN.md through tokens.css. */

/* ---------- 1. Calendar ---------- */

.k-heat {
  --k-heat-cell: 0.875rem;   /* the source's 14px cell */
  --k-heat-gap: var(--s1);   /* on an 18px pitch */
  position: relative;
  font-family: var(--sans);
  font-size: 0.8125rem;
  line-height: 1rem;
  color: var(--lichen);
}

/* The scroller reaches half a step past the root on each side so the focus ring
   on an edge cell is never clipped, and the grid still lines up flush left.
   A right-to-left scroller starts at its right edge, which puts the newest week
   in view first without any script (and before the element has a size). */
.k-heat-scroll {
  margin: 0 calc(var(--s2) * -1);
  overflow-x: auto;
  overflow-y: hidden;
  direction: rtl;
}
.k-heat-body {
  direction: ltr;
  width: -webkit-max-content;
  width: max-content;
  margin-right: auto;        /* flush left whenever the weeks fit */
  padding: 0 var(--s2) var(--s2);
}

.k-heat-months {
  position: relative;
  height: 1rem;
  margin-bottom: var(--s2);
}
.k-heat-month {
  position: absolute;
  top: 0;
  white-space: nowrap;
}

.k-heat-grid {
  display: flex;
  flex-direction: column;
  gap: var(--k-heat-gap);
}
.k-heat-line {
  display: flex;
  gap: var(--k-heat-gap);
}

.k-heat-cell,
.k-heat-swatch {
  position: relative;
  flex: none;
  display: block;
  width: var(--k-heat-cell);
  height: var(--k-heat-cell);
  border-radius: var(--r-page);
}
.k-heat-cell {
  cursor: default;
  -webkit-tap-highlight-color: transparent;
}

/* Hit area: the cell plus half the gap on every side, so the zones tile the whole
   grid and a pointer or a finger never falls through a gap. */
.k-heat-cell::before {
  content: "";
  position: absolute;
  top: calc(var(--k-heat-gap) * -0.5);
  right: calc(var(--k-heat-gap) * -0.5);
  bottom: calc(var(--k-heat-gap) * -0.5);
  left: calc(var(--k-heat-gap) * -0.5);
}

/* The painted square. Opacity lives here, not on the cell, so the ring around a
   pale day stays at full strength. */
.k-heat-cell::after,
.k-heat-swatch::after {
  content: "";
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  border-radius: var(--r-page);
  background: var(--rule);
}
.k-heat-cell[data-level="1"]::after, .k-heat-swatch[data-level="1"]::after { background: var(--moss); opacity: 0.3; }
.k-heat-cell[data-level="2"]::after, .k-heat-swatch[data-level="2"]::after { background: var(--moss); opacity: 0.5; }
.k-heat-cell[data-level="3"]::after, .k-heat-swatch[data-level="3"]::after { background: var(--moss); opacity: 0.75; }
.k-heat-cell[data-level="4"]::after, .k-heat-swatch[data-level="4"]::after { background: var(--moss); opacity: 1; }

/* The day the tooltip is reading out. Same ring as keyboard focus. */
.k-heat-cell.k-heat-on {
  z-index: 1;
  outline: 2px solid var(--moss);
  outline-offset: 2px;
}
.k-heat-cell:focus-visible { z-index: 1; }

.k-heat-legend {
  display: flex;
  align-items: center;
  gap: var(--s1);
  margin-top: var(--s2);
}
.k-heat-word:first-child { margin-right: var(--s1); }
.k-heat-word:last-child { margin-left: var(--s1); }

/* One tooltip for the whole grid. The outer box is moved by script; the inner
   bubble fades (120ms in with a 3px rise, 120ms out, from the source). The
   padding is the space above the day: the source's 4px plus the 4px the ring
   now takes, so the bubble never sits on the ring. */
.k-heat-tip {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 2;
  max-width: 100%;
  padding-bottom: var(--s2);
  pointer-events: none;
}
.k-heat-tip-in {
  display: block;
  padding: var(--s1) var(--s2);
  border-radius: var(--r-page);
  background: var(--sheet);
  box-shadow: var(--lift);
  color: var(--ink);
  font-variant-numeric: tabular-nums;
  overflow-wrap: break-word;
  opacity: 0;
  transform: translateY(3px);
  transition: opacity 120ms linear, transform 0s linear 120ms;
}
.k-heat-tip.k-heat-show .k-heat-tip-in {
  opacity: 1;
  transform: none;
  transition: opacity 120ms linear, transform 120ms var(--ease);
}

/* ---------- 2. Figures ---------- */

/* <dl class="k-heat-figures"><div><dt>Days written</dt><dd>41</dd></div> ... </dl>
   Label and figure share one size; only weight and tone differ. No boxes. */
.k-heat-figures {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s1) var(--s4);
  margin: 0 0 var(--s3);
  font-family: var(--sans);
  font-size: 0.9375rem;
  line-height: 1.5rem;
  font-variant-numeric: tabular-nums;
  color: var(--lichen);
}
.k-heat-figures > div {
  display: flex;
  align-items: baseline;
  gap: var(--s2);
}
.k-heat-figures dt,
.k-heat-figures dd { margin: 0; }
.k-heat-figures dd {
  color: var(--ink);
  font-weight: 500;
}

/* ---------- 3. Glide ---------- */

/* The list becomes its own stacking context and the wash sits at the back of it,
   so rows need no position or z-index of their own. Rows must not paint an
   opaque background, or they will cover it. */
.k-heat-glide {
  position: relative;
  z-index: 0;
}
.k-heat-glide > .k-heat-glide-hl {
  position: absolute;
  top: 0;
  left: 0;
  z-index: -1;
  display: block;
  width: 0;
  height: 0;
  margin: 0;
  padding: 0;
  border: 0;
  list-style: none;
  pointer-events: none;
  border-radius: var(--r-page);
  background: var(--wash);
  opacity: 0;
  /* source: spring with duration 0.08 and no bounce; exit fade 0.06 */
  transition: transform 80ms var(--ease), width 80ms var(--ease), height 80ms var(--ease), opacity 60ms linear;
}
.k-heat-glide > .k-heat-glide-hl.k-heat-show {
  opacity: 1;
  transition: transform 80ms var(--ease), width 80ms var(--ease), height 80ms var(--ease), opacity 80ms linear;
}

@media (prefers-reduced-motion: reduce) {
  .k-heat-tip-in,
  .k-heat-tip.k-heat-show .k-heat-tip-in,
  .k-heat-glide > .k-heat-glide-hl,
  .k-heat-glide > .k-heat-glide-hl.k-heat-show { transition: none; }
  .k-heat-tip-in { transform: none; }
}


/* ===== choose ===== */
/* kit choose: a drawn scale, a drawn tick and a title edited in place. See
   the section of the same name in kit.js for the sources on 21st.dev. All
   three are pen lines: --stroke thick, round caps, never scaled. */

/* ---------- 1. Scale ---------- */
/* <span class="k-scale" role="radiogroup"> built by Kit.scale. One line, a
   tick at each stop, the two words under its ends. A stop's box is its hit
   area and holds the word under it too, so the line costs no more height
   than the hit area: 2.5rem, and never under 48px on touch. The mark is the
   ink dots' measure (0.75rem), and a tick is as tall. On the page the line
   and ticks are edge, the words lichen and the mark moss; --k-scale-line and
   --k-scale-mark change that (the toast sets both to its own text colour). */
.k-scale {
  --k-scale-line: var(--edge); --k-scale-mark: var(--moss);
  position: relative; display: block; min-width: 0;
  color: var(--lichen); font: 400 0.8125rem/1rem var(--sans);
}
.k-scale__track { position: relative; display: flex; }
.k-scale__line {
  position: absolute; left: 0; top: calc(var(--s2) + 0.125rem); display: block; width: 100%; height: var(--stroke-h);
  overflow: visible; pointer-events: none; color: var(--k-scale-line);
}
.k-scale__line path, .k-scale__tick path {
  fill: none; stroke: currentColor; stroke-width: var(--stroke);
  stroke-linecap: round; stroke-linejoin: round; vector-effect: non-scaling-stroke;
}
.k-scale__stop {
  position: relative; flex: 1 1 0; min-width: 0; height: 2.5rem; margin: 0; padding: var(--s2) 0 0; border: 0;
  display: flex; justify-content: center; align-items: flex-start;
  background: none; color: inherit; border-radius: var(--r-ctl); cursor: pointer;
}
.k-scale__tick { display: block; width: var(--stroke-h); height: 0.75rem; overflow: visible; color: var(--k-scale-line); transition: transform var(--t-fast) var(--ease); }
.k-scale__mark {
  position: absolute; top: var(--s2); left: 50%;
  width: 0.75rem; height: 0.75rem; margin-left: -0.375rem; border-radius: 50%;
  background: var(--k-scale-mark); pointer-events: none;
}
.k-scale__mark[hidden] { display: none; }
.k-scale__ends {
  position: absolute; left: 0; right: 0; bottom: 0; display: flex; justify-content: space-between;
  pointer-events: none;
}
@media (hover: hover) {
  .k-scale__stop:hover .k-scale__tick { color: var(--k-scale-mark); transform: scaleY(1.25); }
}
@media (pointer: coarse), (hover: none) { .k-scale__stop { height: max(2.5rem, 48px); } }
@media (forced-colors: active) { .k-scale__mark { background: Highlight; } }

/* ---------- 2. Tick ---------- */
/* <ul class="k-ticks"><li><label class="k-tickrow"><input type="checkbox">
   <span class="k-tick">…</span><span>words</span></label></li></ul>
   The whole row is the label. The checkbox is real and invisible; the mark
   beside it is a small pen-drawn square and, once chosen, a moss tick over
   it that runs out past the corner. --k-tick-lh is the line height of the words beside the mark, so the
   two sit on one line. */
.k-ticks { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--rule); }
.k-tickrow {
  --k-tick-lh: 1.75rem;
  position: relative; display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 0 var(--s3);
  min-height: var(--h-tap); padding: var(--s3) 0; border-bottom: 1px solid var(--rule);
  cursor: pointer; -webkit-tap-highlight-color: transparent;
}
.k-tickrow input {
  position: absolute; top: 0; left: 0; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: inherit;
  -webkit-appearance: none; appearance: none;
}
.k-tick { display: flex; align-items: center; height: var(--k-tick-lh); }
.k-tick__svg { display: block; width: 1rem; height: 1rem; overflow: visible; border-radius: var(--r-page); }
.k-tick path {
  fill: none; stroke: currentColor; stroke-width: var(--stroke);
  stroke-linecap: round; stroke-linejoin: round; vector-effect: non-scaling-stroke;
}
.k-tick__box { color: var(--edge); }
/* Out: the source's 120ms ease-in, down to a quarter and 8 degrees back. */
.k-tick__check {
  color: var(--moss); opacity: 0;
  transform-box: fill-box; transform-origin: 25% 90%; transform: scale(0.25) rotate(-8deg);
  transition: transform 120ms var(--ease-exit), opacity 120ms var(--ease-exit);
}
/* In: the source's spring, which is critically damped and settles in about 160ms. */
.k-tickrow input:checked + .k-tick .k-tick__check {
  opacity: 1; transform: none;
  transition: transform 160ms cubic-bezier(0.2, 0.9, 0.3, 1), opacity 80ms linear;
}
/* The input is invisible, so the same global ring is drawn on the mark. */
.k-tickrow input:focus { outline: none; }
.k-tickrow input:focus-visible + .k-tick .k-tick__svg { outline: 2px solid var(--moss); outline-offset: 4px; }
@supports not selector(:focus-visible) {
  .k-tickrow input:focus + .k-tick .k-tick__svg { outline: 2px solid var(--moss); outline-offset: 4px; }
}
@media (hover: hover) { .k-tickrow:hover .k-tick__box { color: var(--moss); } }
@media (forced-colors: active) { .k-tick__check { color: Highlight; } }

/* ---------- 3. Title edited in place ---------- */
/* <div class="k-inline k-inline--title"><textarea class="k-inline__field" rows="1">
   </textarea><label class="k-inline__pen" for="…">pencil</label></div>
   Literata with no box: italic at the heading size for a title, roman at the
   excerpt size for the quieter line under it (k-inline--line). The pencil says
   the words can be changed and steps aside while they are. Grow the field
   with Kit.autogrow so a long title wraps instead of running out of sight. */
.k-inline { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: start; }
.k-inline__field {
  display: block; width: 100%; min-width: 0; margin: 0; padding: var(--s2) 0; border: 0; background: none; resize: none;
  color: var(--ink); font-family: var(--serif); border-radius: var(--r-page); overflow-wrap: anywhere;
  -webkit-appearance: none; appearance: none;
}
.k-inline__field::placeholder { color: var(--lichen); opacity: 1; }
.k-inline--title .k-inline__field { font-style: italic; font-weight: 500; font-size: 1.5rem; line-height: 2rem; }
.k-inline--line .k-inline__field { font-weight: 400; font-size: max(16px, 1rem); line-height: 1.5rem; padding: var(--s1) 0; }
.k-inline__pen {
  display: flex; align-items: center; justify-content: flex-end; width: var(--s5); height: var(--h-tap);
  color: var(--lichen); cursor: pointer; transition: opacity var(--t-fast) var(--ease);
}
.k-inline__pen svg { width: 1.25rem; height: 1.25rem; }
.k-inline__field:focus + .k-inline__pen { opacity: 0; pointer-events: none; }
@media (hover: hover) { .k-inline__pen:hover { color: var(--ink); } }
