/* Geist, self-hosted. Basecoat's --font-sans has asked for it since the day it
   was vendored — the stack starts "Geist Sans" — but the file was never here,
   so every page has been rendering in the system font the fallback names. One
   variable file covers every weight, which is what makes 550 an actual weight
   rather than a rounding to the nearest static cut.
   SIL Open Font License 1.1; the licence travels with it in geist-LICENSE.txt. */
@font-face {
  font-family: "Geist Sans";
  src: url("geist-variable.woff2") format("woff2-variations");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

/* Its monospace twin, for the handful of literals someone has to type:
   /status, /stop, /start and the delete phrase. Basecoat already points
   code/kbd/samp/pre at --font-mono, which names this first — so loading the
   face is the whole change. */
@font-face {
  font-family: "Geist Mono";
  src: url("geist-mono-variable.woff2") format("woff2-variations");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

/* Light mode only (spec decision 6): no .dark class is ever added, and this
   pins native widgets and scrollbars too. Layout helpers only — Basecoat
   styles the components. */
:root {
  color-scheme: light;
  /* lucide check and x, as masks so the size is ours rather than a font's. */
  --icon-check: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E");
  --icon-cross: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M18 6 6 18'/%3E%3Cpath d='m6 6 12 12'/%3E%3C/svg%3E");
  /* The one curve in the app, easeOutQuint. It was already here as a literal on
     the alert stack; naming it is what stops the next animation inventing a
     second ease-out that is almost but not quite this one. Never ease-in: it
     starts slow, which delays the exact frame the eye is on. */
  --ease-out-quint: cubic-bezier(.22, 1, .36, 1);
}
/* A column the height of the window, so a short page still puts the footer on
   the bottom edge rather than leaving it stranded under the last paragraph. */
body {
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  margin: 0;
  /* Basecoat's own stack, which names Geist first and falls back to the system
     font — the list this used to hard-code without the font at the front. */
  font-family: var(--font-sans, ui-sans-serif, system-ui, sans-serif);
  /* macOS draws text heavier than iOS does, which is why one weight could not
     look right on both. This makes the desktop render the way the phone always
     has. It lightens the whole page rather than the headings alone, and Firefox
     ignores it — so the weights above are still set for the phone, and this
     brings the Mac to them rather than the other way round. */
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  /* Not --background: that token is white and the cards' --color-card follows
     it, so tinting the token would tint the cards too. The page sits behind
     them instead, which is what gives them an edge. */
  background: #fafafa;
  color: var(--foreground, #111);
}
/* Grows to take whatever the footer does not, which is what pushes the footer
   down; the auto margins still centre it. align-content packs the rows at the
   top of that grown box — without it a grid stretches its rows to fill, and a
   short page spreads itself across the window instead of sitting at the top. */
/* Headings only. Basecoat carries the tracking token but applies it in a few
   places rather than to headings generally.
   450 rather than 500: the stack resolves to a variable face (SF Pro, Segoe UI
   Variable, Roboto), so the half step is a real weight and not a rounding. On a
   platform with only static weights it lands on whichever of 400/500 is nearer,
   which is where it would have been anyway. */
h1, h2 {
  letter-spacing: var(--tracking-tight, -.025em);
  font-weight: 550;
}

.page {
  max-width: 42rem; margin: 0 auto; padding: 2rem 1rem;
  display: grid; gap: 1.5rem; align-content: start;
  flex: 1 0 auto;
}
/* Behind the login the page is a column of cards, and the gap between them is
   the page's whole rhythm — a wide one only adds scrolling. The pitch page
   keeps 1.5rem: it is an argument rather than a list, and it wants the air. */
.page.stacked { gap: 1.25rem; }
.stack { display: grid; gap: 1rem; }
.row { display: flex; gap: .5rem; align-items: center; flex-wrap: wrap; }
.between { justify-content: space-between; }
.end { justify-content: flex-end; }
/* What the card used to hold, now just a column on the page. Its headings are
   the page's, not a label over a value the way .eyebrow is on the dashboard, so
   they keep the foreground. */
.pitch { display: grid; gap: 1rem; }
.pitch .eyebrow { color: var(--color-foreground, #0a0a0a); font-weight: 550; }

/* The close of the argument, centred under it. Right-aligned made sense while
   the lists sat in a card with an edge to end at; on the open page it just
   drifted away from the column it belongs to. */
.signin {
  display: grid; justify-items: center; gap: .5rem;
  margin-top: .75rem;
}
.signin p { margin: 0; font-size: 13px; }
.muted { color: var(--muted-foreground, #666); font-size: .875rem; }
.mt { margin-top: .5rem; }
/* An empty status element is still a grid item, so without this the .stack gap
   holds a blank row where the status line used to be. */
#watcher-status:empty { display: none; }
/* transitions.dev's toast entrance, in place of Basecoat's 0.3s ease-in-out
   keyframe. It rises, fades, un-blurs and settles out of a 0.97 scale, on the
   slower clock opening and a faster one closing — one class, both directions.
   Guarded on [data-enhanced], which toast.js sets: without it the closed state
   below would apply with nothing left to open it, and a page with a blocked
   script would hold an invisible message. */
.toaster[data-enhanced] .toast {
  animation: none;
  opacity: 0;
  transform: translateY(16px) scale(.97);
  filter: blur(2px);
  will-change: transform, opacity, filter;
  transition:
    opacity .25s var(--ease-out-quint),
    transform .25s var(--ease-out-quint),
    filter .25s var(--ease-out-quint);
}
.toaster[data-enhanced] .toast.is-open {
  opacity: 1;
  transform: none;
  filter: blur(0);
  transition:
    opacity .35s var(--ease-out-quint),
    transform .35s var(--ease-out-quint),
    filter .35s var(--ease-out-quint);
}
@media (prefers-reduced-motion: reduce) {
  /* The rise and the blur go; the fade stays, because a message appearing with
     no transition at all is the jump this is here to prevent. */
  .toaster[data-enhanced] .toast { transform: none; filter: none; transition: opacity .15s ease; }
  .toaster[data-enhanced] .toast.is-open { transform: none; filter: none; transition: opacity .15s ease; }
}

/* Basecoat gives the toast no tone of its own, so an error would otherwise
   look exactly like a confirmation. */
.toast[data-tone="error"] .toast-content { color: var(--color-destructive, #b91c1c); }
/* Basecoat breaks the toast body mid-word (word-break: break-all), which turns
   a wrapped time or number into nonsense. Break between words, and only inside
   one when a single word genuinely cannot fit. leading-snug is Tailwind's
   1.375, which Basecoat's build does not ship as a utility. */
.toast .toast-content section p {
  word-break: normal; overflow-wrap: anywhere; line-height: 1.375;
}
/* Basecoat styles .btn and .badge, not bare anchors, so a link inside running
   text would otherwise be indistinguishable from the words around it. Darker
   than the text it sits in where that text is muted, and always underlined. */
.muted a, .ticks a {
  color: var(--foreground, #111);
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* The page title and its tagline read as one block, not two paragraphs. The
   weight is explicit because Basecoat ships a Tailwind preflight, which resets
   headings to inherit the body weight. */
/* Listed twice on purpose: inside a card header, Basecoat's own
   `.card > header > h2` rule is the more specific of the two. */
.brand, .card > header > .brand {
  display: flex; align-items: center; gap: .4rem;
  margin: 0; font-size: 1.4rem; font-weight: 550; line-height: 1.2;
}
/* rem, not em: the wordmark grew and the clover did not follow it. 1.74rem is
   the size it already had beside the 1.2rem type. */
.brand img { width: 1.74rem; height: 1.74rem; }
/* The row is centred on the clover, which is taller than the wordmark, so a
   centred badge floats above the text. Sit it on the bottom of the line and
   nudge it back up by the difference. */
.brand .badge { align-self: flex-end; margin-bottom: .11rem; }
.masthead p { margin: .25rem 0 0; }
/* The headline the whole page argues for. */
.headline {
  margin: 0;
  text-align: center;
  font-size: 1.4rem;
  font-weight: 550;
  line-height: 1.15;
  text-wrap: balance;
}

/* The alert mockup on the login page. Narrower than the card it sits above, so
   it reads as a phone's worth of notifications rather than another panel —
   until the screen is small enough that the inset is just lost width. */
/* width, not max-width: the auto margins below turn off this grid item's
   stretch, and with every card absolutely positioned the stack has nothing
   left in flow to take a width from — it collapses to the caption.
   29rem is the longest line any alert has in either language — "I'm checking
   your calendar and will tell you the moment a slot opens." at 417px — plus the
   card's 28px of padding and a little slack. Narrower than that and the cards
   start wrapping a sentence that was written to sit on one line. */
.alert-demo { width: min(100%, 29rem); margin: 0 auto; }
.alert-demo-stack { display: grid; gap: .5rem; }
/* Whose messages these are, sitting right on top of them. */
/* Pulled down into the stack's top. That space is reserved for the cards
   behind the front one, and they only ever rise into the lower half of it, so
   this closes the gap without anything reaching the badge. */
.alert-demo-who { margin: 0 0 -.25rem; text-align: center; position: relative; z-index: 4; }
/* Basecoat's badge is built for 12px and pins its icon there with !important,
   which is why both have to be said again. Height goes to auto so the taller
   text is not clipped by the fixed one. */
.alert-demo-who .badge {
  height: auto;
  /* A shade more on the right: the circle on the left carries its weight
     inward, so an even pair reads as crowded on the text side. */
  padding: .25rem .725rem .25rem .625rem;
  font-size: 14px;
  font-weight: 500;
  gap: .375rem;
}
/* Scaled rather than resized. Basecoat is built with Tailwind v4, so its rule
   sits inside an @layer — and an !important declaration inside a layer beats an
   !important one outside every layer, whatever the specificity. Fighting that
   needs a layer of our own; a transform needs nothing. */
.alert-demo-who .badge > svg { transform: scale(1.3); }
/* It is a link, so it should feel like one under the cursor without announcing
   itself as a second button. */
.alert-demo-who .badge { text-decoration: none; transition: opacity .15s ease; }
.alert-demo-who .badge:hover { opacity: .85; }

/* The way out of a dead end, on whatever page the dead end is. Outside .page,
   so it carries that column's width and gutters itself. */
.site-footer {
  flex: none;
  width: 100%; max-width: 42rem; margin: 0 auto;
  padding: 1rem 1rem 2rem;
  text-align: center; font-size: 13px;
}
.site-footer p { margin: 0; color: var(--color-muted-foreground, #71717a); }
.site-footer a { color: var(--color-foreground, #0a0a0a); text-decoration: underline; text-underline-offset: 2px; }

/* .muted carries the size and colour, the same as "¿Listo para empezar?" over
   the button at the other end of the page — the two lines that invite somebody
   in should not be two different sizes of quiet. */
.alert-demo-lead { margin: 0 0 .35rem; text-align: center; font-size: 13px; }

/* Points back at the stack above it, so it reads as a label on the thing
   rather than the start of the next section. */
.alert-demo-note {
  display: flex; align-items: center; justify-content: center; gap: .35rem;
  margin: .5rem 0 0;
  font-size: var(--text-xs, .75rem);
  color: var(--color-muted-foreground, #71717a);
}
/* Lifted off the baseline so the arrow reaches back toward the stack. */
.alert-demo-note svg { width: 14px; height: 14px; flex: none; margin-bottom: .5rem; }

.alert-line { display: block; }

@media (max-width: 640px) {
  /* The breaks are for a wide card. On a phone the text wraps where it needs
     to, and an enforced break just costs a line. */
  .alert-line { display: inline; }
  /* The badge and the button at the far end of the page are the only two
     things anyone presses here, and on a phone 14px is a reading size rather
     than a tapping one. The next stop up the scale is 16px. */
  .alert-demo-who .badge {
    font-size: 16px;
    /* The same tenth of a rem more on the right as at 14px, scaled with it. */
    padding: .3rem .8rem .3rem .7rem;
  }
  /* And the mark grows by exactly what the text did, 16/14 — Basecoat pins the
     icon at 12px with an !important inside a layer, so the size is a transform
     rather than a width, and the factor multiplies the one already there. */
  .alert-demo-who .badge > svg { transform: scale(calc(1.3 * 16 / 14)); }
  .signin .btn {
    height: calc(var(--spacing, .25rem) * 10);
    padding-inline: .875rem;
    font-size: var(--text-base, 1rem);
  }
}

/* Stacking only once the script says so: without it the cards stay in flow and
   the illustration is a plain list, which still shows three alerts. */
.alert-demo-stack.is-stacked { display: block; position: relative; }
.is-stacked .alert-demo-card {
  position: absolute; inset-inline: 0; bottom: 0;
  transform-origin: bottom center;
  transition: transform .5s var(--ease-out-quint), opacity .5s ease;
}
/* Depth counts back from the newest, which is the card in front. */
/* For the frame in which the stack jumps rather than moves. */
.alert-demo-stack.instant .alert-demo-card { transition: none; }
.is-stacked .alert-demo-card[data-depth="waiting"] { opacity: 0; transform: translateY(1rem) scale(.96); }
.is-stacked .alert-demo-card[data-depth="0"] { opacity: 1; transform: none; z-index: 3; }
.is-stacked .alert-demo-card[data-depth="1"] { opacity: .65; transform: translateY(-.85rem) scale(.94); z-index: 2; }
.is-stacked .alert-demo-card[data-depth="2"] { opacity: .35; transform: translateY(-1.55rem) scale(.88); z-index: 1; }
.is-stacked .alert-demo-card[data-depth="gone"] { opacity: 0; transform: translateY(-2.1rem) scale(.84); z-index: 0; }
.alert-demo-card {
  background: var(--color-card, #fff);
  border-radius: var(--radius-lg, .625rem);
  padding: .75rem .875rem;
  font-size: 13px;
  line-height: 1.375;
  box-shadow: 0 1px 2px rgb(0 0 0 / .05), 0 0 0 1px rgb(0 0 0 / .06);
}
.alert-demo-card p { margin: 0; }
.alert-demo-card p + p { margin-top: .15rem; color: var(--color-muted-foreground, #71717a); }
/* A shade larger than the line under it: the card is 13px, the title 14px. */
.alert-demo-title { font-size: 14px; font-weight: 500; }
/* The reveal sits inside the field, so the input keeps room for it. */
.password-field { position: relative; }
.password-field .input { padding-inline-end: 2.5rem; }
.password-toggle {
  position: absolute; inset-inline-end: .25rem; top: 50%; translate: 0 -50%;
  display: inline-flex; align-items: center; justify-content: center;
  width: 2rem; height: 2rem; padding: 0;
  border: 0; border-radius: var(--radius-sm, .375rem);
  background: none; cursor: pointer;
  color: var(--color-muted-foreground, #71717a);
}
.password-toggle:hover { color: var(--color-foreground, #0a0a0a); }
.password-toggle svg { width: 1rem; height: 1rem; }

/* Looks like the link the real message carries, without being one. */
.mock-link { color: var(--foreground, #111); text-decoration: underline; text-underline-offset: 2px; }

/* The three setup steps are disclosures: the title is the control, and
   everything under it — the description included — collapses. A shut card is
   then its header alone, which the card's own 1.5rem of padding-block centres
   without anything here having to say so.
   The card's gap goes to zero and the two spacings it used to provide move onto
   the panel's children, because one collapsing box has to carry both: 0.25rem
   under the title for a description, 1.5rem above the body proper. Same two
   numbers as before, said in a different place. */
.step { gap: 0; }
.step > header { padding-inline: 0; }
/* The whole row is the control, so the card's side padding belongs to the
   button rather than to the header around it. */
.step-toggle {
  display: flex; align-items: center; justify-content: space-between; gap: .5rem;
  width: 100%; margin: 0; padding: 0 1.5rem;
  border: 0; background: none; cursor: pointer;
  font: inherit; letter-spacing: inherit; color: inherit; text-align: start;
}
.step-toggle:focus-visible { outline: none; }
.step:has(.step-toggle:focus-visible) {
  outline: 2px solid var(--color-ring, #0a0a0a);
  outline-offset: 2px;
}
/* The open step has nothing left to do — pressing it does not shut it, because
   one of the three is always the one you are on. */
.step[data-open="true"] .step-toggle { cursor: default; }
/* A finished step wears its tick beside its name, where the eye already is —
   the chevron at the far end of the row is about the card, not about the step.
   Bigger than the one in the bot badge on the way in: there it is a flourish
   on a name, here it is the answer to "have I done this one?".
   Inline, so it sits on the title's baseline rather than making the span a flex
   row — step three's status badge shares that span and is placed by the same
   rules it always was. */
.step-done {
  /* inline-block, because Basecoat ships a Tailwind preflight that makes every
     svg a block — left alone it drops onto a line of its own under the title. */
  display: inline-block;
  width: 1.125rem; height: 1.125rem;
  margin-inline-start: .4rem;
  vertical-align: -.2em;
  color: oklch(72.3% 0.219 149.579);
}
/* transitions.dev's success check, on the one frame where the mark is news:
   the load right after you finish a step. steps.js decides that — see there for
   why it is a browser's memory rather than a server's.
   Four of their five animations. The fifth draws the tick's stroke on, and ours
   is a filled path with no stroke to draw; it would need a stroked icon.
   Their distances are tuned for a 48px success icon; this is an 18px mark
   beside a title, so the bob and the blur come down with it. */
.step-done[data-state="in"] {
  transform-origin: center;
  animation:
    check-fade .4s var(--ease-out-quint) forwards,
    check-rotate .4s var(--ease-out-quint) forwards,
    check-blur .4s var(--ease-out-quint) forwards,
    check-bob .4s cubic-bezier(.34, 1.35, .64, 1) forwards;
}
@keyframes check-fade { from { opacity: 0 } to { opacity: 1 } }
@keyframes check-rotate { from { transform: rotate(80deg) } to { transform: rotate(0) } }
@keyframes check-blur { from { filter: blur(4px) } to { filter: blur(0) } }
@keyframes check-bob { from { translate: 0 10px } to { translate: 0 0 } }
@media (prefers-reduced-motion: reduce) {
  .step-done[data-state="in"] { animation: none; }
}

.step-chevron {
  display: inline-flex;
  width: 1rem; height: 1rem; flex: none;
  /* Quiet enough to stay out of the way of the title, dark enough to be there
     at all — anything lighter reads as a smudge on the card rather than a
     control. */
  color: #b7b7b7;
  transition: rotate .2s var(--ease-out-quint);
}
.step[data-open="true"] .step-chevron { rotate: 180deg; }

/* 0fr to 1fr rather than a measured height: the row is sized by its content, so
   nothing has to read scrollHeight and nothing goes stale when the status line
   inside rewrites itself. */
.step-panel {
  display: grid; grid-template-rows: 1fr;
  transition: grid-template-rows .2s var(--ease-out-quint);
}
.step[data-open="false"] .step-panel { grid-template-rows: 0fr; }
/* The clipping has to happen on the item, not the row — and a grid item's
   min-height is its content by default, which would refuse to reach zero. */
.step-panel-inner {
  overflow: hidden; min-height: 0;
  opacity: 1;
  transition: opacity .2s var(--ease-out-quint);
}

/* Out of tab order once it has finished closing, not before: a hidden element
   cannot be reached, and hiding it at 0s would cut the collapse short. One rule
   for the whole shut state — a second one carrying its own `transition` would
   replace this list rather than add to it, and the fade would never run. */
.step[data-open="false"] .step-panel-inner {
  opacity: 0; visibility: hidden;
  transition: opacity .2s var(--ease-out-quint), visibility 0s .2s;
}
.step-panel-inner > * { padding-inline: 1.5rem; }
.step-panel-inner > p { margin: .25rem 0 0; }
.step-panel-inner > section { margin-top: 1.5rem; }

/* Reduced motion keeps the fade — it still says the panel changed — and drops
   the size change, which is the part that moves everything below it. */
@media (prefers-reduced-motion: reduce) {
  .step-panel { transition: none; }
  .step-panel-inner { transition: opacity .15s ease; }
  .step-chevron { transition: none; }
}

/* Basecoat has no card variant, so this is ours: the account card is not one
   of the steps, so it sits on the page instead of lifting off it. The hairline
   edge is a ring rather than a border, so only the drop shadow is cleared —
   zeroing box-shadow outright would take the edge with it. */
.card[data-variant="secondary"] {
  background: transparent;
  /* Both of Tailwind's shadow slots: --tw-shadow is the lift, --tw-ring-shadow
     is the hairline edge. A ring cannot be dashed, so the edge is redrawn as an
     outline — inset by its own width so it lands where the ring did, and unlike
     a border it costs no layout. */
  --tw-shadow: 0 0 #0000;
  --tw-ring-shadow: 0 0 #0000;
  outline: 1px dashed var(--color-border, #e4e4e7);
  outline-offset: -1px;
}

/* What a step currently holds — the pieza on file, the linked chat, what the
   monitor is doing — sits in a panel inside the card, so it reads as the
   card's contents rather than more of its description. */
.inset {
  background: color-mix(in oklab, var(--color-muted, #f4f4f5) 50%, transparent);
  border-radius: var(--radius-md, .5rem);
  padding: 1rem;
}
/* Values keep the foreground; only the labels step back. The panel's own
   background is what sets it apart from the description above it. */
.inset { font-size: var(--text-sm, .875rem); }
.inset p { margin: 0; }
/* A sentence sitting straight in a panel is not a value — "Linked. Alerts and
   /status work in your chat.", the monitor's own status line — so it does not
   get the weight a value does. A step darker than the muted grey the labels
   use: it is the panel's content, not a note about it. */
.inset:not(.inset-note) > p { color: #52525b; }
.inset > * + * { margin-top: .75rem; }
/* A label belongs above its value, never beside it — some of these values are
   a whole office name and would push the label off the line. */
.inset-pair { display: grid; gap: .125rem; }
/* Guidance rather than a value, so the sentence steps back — but the thing you
   actually have to press does not. */
.inset-note { color: var(--color-muted-foreground, #71717a); }
.inset-note .literal { color: var(--color-foreground, #0a0a0a); }

/* As much air below the panel as above it. 1.5rem is the gap the card's own
   padding already leaves between the description and the panel's top. */
.inset + * { margin-top: 1.5rem; }

.eyebrow {
  font-size: var(--text-xs, .75rem);
  font-weight: 500;
  letter-spacing: .05em;
  text-transform: uppercase;
  color: var(--color-muted-foreground, #71717a);
}

/* Lists are unstyled by the preflight, so the marker is ours. A tick and a
   cross carry the difference between the two lists on their own; colouring
   both would say it twice. */
.ticks { display: grid; gap: .5rem; margin-top: .5rem; }
/* The size lives on the row, not on the span: the marker is a ::before on the
   li, so if only the span were 14px the two would sit on different baselines
   and the tick would ride above its own sentence. */
.ticks li {
  display: grid; grid-template-columns: 1rem 1fr; gap: .5rem;
  align-items: start; font-size: 14px; line-height: 1.2;
  letter-spacing: var(--tracking-tight, -.025em);
}
/* The claim steps back; the mark in front of it does not — it is the part
   doing the sorting. */
.ticks li > span { color: var(--color-muted-foreground, #71717a); }
/* Drawn, not typed. These were the characters ✓ and ✕, which meant their size
   came from whichever installed font happened to carry them — and Geist does
   not, so iOS fell back to a face with different metrics and rendered them
   smaller than everything around them. A masked SVG is the same 14px on every
   platform and still takes its colour from CSS. */
.ticks li::before {
  content: "";
  width: 14px;
  height: 1.2em;
  background-color: var(--color-muted-foreground, #71717a);
  -webkit-mask: var(--icon-check) no-repeat center / 14px 14px;
  mask: var(--icon-check) no-repeat center / 14px 14px;
}
.ticks.crosses li::before {
  -webkit-mask-image: var(--icon-cross);
  mask-image: var(--icon-cross);
}

/* Safari on iOS styles a date input itself and gives the value inside it
   margins of its own, so the control sits wider than the column every other
   field lines up with. */
.field > input[type="date"] { -webkit-appearance: none; appearance: none; width: 100%; min-width: 0; }
.field > input[type="date"]::-webkit-date-and-time-value { margin: 0; text-align: start; }

/* The hint under a control: 12px, and tucked up against the input it explains
   rather than sitting the full field gap away from it. The label above keeps
   Basecoat's own size and spacing. */
.field > p { font-size: 12px; margin-top: -.375rem; }

/* Basecoat's preflight gives <code> a monospace face and nothing else, so a
   literal sitting in a sentence has no edge against the prose around it. */
code {
  /* --color-border, not --color-muted: both panels and code were at 97%
     lightness, so a literal inside a panel had no edge at all. */
  background: var(--color-border, #e4e4e7);
  border-radius: var(--radius-sm, .375rem);
  padding: .1em .35em;
  font-size: .9em;
}
/* The tagline is long enough to push the language select onto its own line.
   Letting the masthead shrink makes the tagline wrap inside itself instead,
   which is what keeps the select in the corner. */
/* nowrap is the load-bearing half: a flex line wraps on the items' unshrunk
   widths, so min-width alone would still push the select onto its own row. */
.page-header { flex-wrap: nowrap; align-items: flex-start; }
.page-header .masthead { flex: 1 1 auto; min-width: 0; }
