/* mandala.computer — site-wide styles.

   "Paper": a warm paper ground, a monospace display face at heavy negative
   tracking, hairline borders in place of shadows, and an ochre/teal accent pair
   that never sits behind body text. Chosen over the previous dark sheet after an
   A/B at dev.mandala.computer (OPL-3820); that preview and its vhost are gone.

   The app follows the same palette, under one extra rule it needs and this file
   does not: chrome is paper, and anything showing a machine's own pixels is a
   stage that stays black. See web/app/globals.css in mandalacomputer/app. The
   two palettes are meant to agree — update them together.

   --green keeps its name and holds ochre. Several pages carry inline
   style="color:var(--green)" and the app uses the same token name; renaming it
   would mean touching HTML for no visible gain.

   Fonts are self-hosted. They were on Google Fonts over @import while this was
   a preview, which is a third-party dependency on first paint and a request
   chain the stylesheet has to finish before anything renders. Both faces are
   SIL Open Font License 1.1 — Inter (Rasmus Andersson) and Geist Mono (Vercel).
*/

@font-face {
  font-family: 'Geist Mono';
  font-style: normal;
  /* One file per subset rather than one per weight: these are VARIABLE fonts,
     and the four weights requested from Google came back as identical bytes
     every time. Declaring the axis range means Geist Mono downloads once and the
     browser interpolates every weight this site uses out of it. */
  font-weight: 100 900;
  font-display: swap;
  src: url('/assets/fonts/GeistMono-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Geist Mono';
  font-style: normal;
  /* One file per subset rather than one per weight: these are VARIABLE fonts,
     and the four weights requested from Google came back as identical bytes
     every time. Declaring the axis range means Geist Mono downloads once and the
     browser interpolates every weight this site uses out of it. */
  font-weight: 100 900;
  font-display: swap;
  src: url('/assets/fonts/GeistMono-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  /* One file per subset rather than one per weight: these are VARIABLE fonts,
     and the four weights requested from Google came back as identical bytes
     every time. Declaring the axis range means Inter downloads once and the
     browser interpolates every weight this site uses out of it. */
  font-weight: 100 900;
  font-display: swap;
  src: url('/assets/fonts/Inter-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  /* One file per subset rather than one per weight: these are VARIABLE fonts,
     and the four weights requested from Google came back as identical bytes
     every time. Declaring the axis range means Inter downloads once and the
     browser interpolates every weight this site uses out of it. */
  font-weight: 100 900;
  font-display: swap;
  src: url('/assets/fonts/Inter-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

:root {
  --bg: #faf8f5;          /* paper, not white */
  --panel: #f2efe8;       /* recessed chrome: title bars, desktop ground */
  --card: #ffffff;        /* raised surfaces sit lighter than the page */
  --border: #e6e2d9;      /* hairline, warm-biased to match the ground */
  --text: #161513;
  --muted: #6e6b61;
  --accent: #161513;      /* primary button fill is ink, not colour */
  --green: #b4791f;       /* ochre. Name kept — see header note. */
  --accent-text: #8a5a12; /* readable ochre text on paper, panel, and white */
  --green-dim: rgba(180,121,31,.12);
  --teal: #2e7d6b;        /* state only: live, done, ✓ */
  --term: #0c0c0b;        /* the terminal stays dark on paper */
  --term-fg: #d7d3c9;
  --display: "Geist Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
  --body: Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
}
* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
body {
  background: var(--bg);
  color: var(--text);
  font: 400 16px/1.62 var(--body);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}
main { flex: 1; }
a { color: inherit; }
/* width:100% is load-bearing and is a fix, not a restyle. body is a column
   flex container, so a .wrap that is a DIRECT child of body — the nav and the
   footer, on every page — becomes a flex item and shrink-to-fits its content
   instead of stretching. On the live apex that leaves the nav starting ~170px
   right of the headline it sits above; centred copy hides it, left-aligned
   copy does not. The same one-liner belongs in site/assets/site.css. */
.wrap { max-width: 1080px; width: 100%; margin: 0 auto; padding: 0 24px; }

/* The stock stylesheet ships no focus ring at all. Paper is a fresh sheet,
   so it gets one — ochre reads clearly on the paper ground. */
:focus-visible { outline: 2px solid var(--green); outline-offset: 3px; border-radius: 4px; }

h1, h2, h3, .price, .tier .pr {
  font-family: var(--display);
  font-weight: 500;
  letter-spacing: -.035em;
  text-wrap: balance;
}

/* ── Nav ─────────────────────────────────────────────────────────── */
nav.site {
  display: flex; align-items: center; gap: 26px; flex-wrap: wrap;
  padding: 22px 0;
  font-size: 14px;
}
.brand {
  display: flex; align-items: center; gap: 10px; margin-right: auto;
  font-family: var(--display); font-weight: 500; font-size: 16.5px;
  letter-spacing: -.03em; text-decoration: none;
}
nav.site a:not(.brand):not(.btn) { color: var(--muted); text-decoration: none; }
nav.site a:not(.brand):not(.btn):hover { color: var(--text); }
nav.site a.active { color: var(--text); }
/* The in-page mark is monochrome for the same reason the tab icon is: ochre
   reads as hue in a rule or a kicker and as value in a filled form, and a
   filled form wants luminance. This makes the nav a single ink lockup, mark and
   wordmark together — which is also what the reference does. Ochre keeps every
   other job in this sheet; it just does not get the mark. */
.mark { width: 24px; height: 24px; flex: none; color: var(--text); }

/* ── Buttons ─────────────────────────────────────────────────────── */
.btn {
  display: inline-block; background: var(--accent); color: var(--bg);
  text-decoration: none; padding: 10px 18px; border-radius: 8px;
  font-weight: 600; font-size: 13.5px; border: 1px solid var(--accent);
}
.btn:hover { background: #000; border-color: #000; }
.btn.ghost { background: transparent; color: var(--text); border-color: var(--border); }
.btn.ghost:hover { background: var(--card); border-color: #d6d1c4; }
.btn.big { padding: 12px 22px; font-size: 15px; }

/* ── Hero ────────────────────────────────────────────────────────── */
/* Left-aligned, not centred. The reference pairs its headline with a code
   block in the right column; our hero's companion is a 940px product shot,
   which will not survive being squeezed into half a column — so the text
   goes left and the shot runs full width beneath it. */
.hero { position: relative; text-align: left; padding: 84px 0 76px; }
.mandala-bg { display: none; }   /* Paper has no rotating mandala */
.hero-inner { position: relative; }
.pill {
  display: inline-block; margin-bottom: 24px; padding: 5px 13px;
  border: 1px solid var(--border); border-radius: 999px; background: var(--card);
  color: var(--muted); font: 400 12px/1 var(--display); letter-spacing: .02em;
}
.pill b { color: var(--accent-text); font-weight: 500; }
h1 {
  font-size: clamp(38px, 6vw, 54px); line-height: 1.04;
  margin: 0 0 22px; max-width: 16ch;
}
h1 .g { color: var(--green); }
.lede {
  font-size: clamp(16.5px, 2vw, 19px); color: var(--muted);
  max-width: 44ch; margin: 0 0 32px;
}
.actions { display: flex; gap: 10px; justify-content: flex-start; flex-wrap: wrap; }
.subnote { margin-top: 18px; color: var(--muted); font: 400 12.5px/1.6 var(--display); }

/* ── Hero product shot ───────────────────────────────────────────── */
.shot {
  display: grid; grid-template-columns: 1.5fr 1fr; text-align: left;
  border: 1px solid var(--border); border-radius: 14px; overflow: hidden;
  background: var(--card);
  box-shadow: 0 30px 70px -46px rgba(22,21,19,.45);
  max-width: 100%; margin: 56px 0 0;
}
@media (max-width: 820px) { .shot { grid-template-columns: 1fr; } }
.desk {
  border-right: 1px solid var(--border); min-height: 340px; position: relative;
  background: var(--panel);
}
@media (max-width: 820px) { .desk { border-right: none; border-bottom: 1px solid var(--border); } }
.desk .topbar {
  display: flex; align-items: center; gap: 10px; padding: 10px 14px;
  background: var(--card); border-bottom: 1px solid var(--border);
  font-size: 11.5px; color: var(--muted);
}
.desk .topbar .mono { font-family: var(--display); }
.dwin {
  position: absolute; background: var(--card); border: 1px solid var(--border);
  border-radius: 7px; overflow: hidden; font-size: 11px;
  box-shadow: 0 14px 34px -20px rgba(22,21,19,.5);
}
.dwin .tb { padding: 6px 12px; font: 400 10.5px/1.5 var(--display); color: var(--muted); border-bottom: 1px solid var(--border); }
.dwin .cn { padding: 10px 12px; line-height: 1.6; color: var(--muted); }
.dwin .cn b { color: var(--text); font-weight: 600; }
.dw1 { top: 56px; left: 26px; width: 62%; }
.dw2 { top: 158px; left: 22%; width: 60%; }
/* The terminal keeps its dark ground — a lit rectangle on paper, which is
   what a terminal looks like on any real desktop. */
.dw2 .cn { font: 400 10.5px/1.7 var(--display); background: var(--term); color: #7fc4a8; min-height: 84px; }
.dw2 .cn .dim { color: #8c887e; }
.agent-cursor {
  position: absolute; top: 215px; left: 56%; width: 15px; height: 15px; z-index: 3;
  animation: drift 7s ease-in-out infinite alternate;
}
@keyframes drift {
  0%   { transform: translate(0, 0); }
  50%  { transform: translate(-130px, -70px); }
  100% { transform: translate(50px, -115px); }
}
/* The cursor ships fill="#fff" stroke="#333" inline — invisible on paper.
   A CSS declaration outranks a presentation attribute, so it inverts here
   without touching the markup. */
.agent-cursor svg path { fill: var(--text); stroke: var(--bg); }
.agent-cursor svg { filter: drop-shadow(0 2px 5px rgba(22,21,19,.35)); }
.agent-cursor .tag {
  position: absolute; top: 14px; left: 12px; background: var(--accent-text); color: #fff;
  font: 500 9.5px/1.6 var(--display); padding: 2px 7px; border-radius: 4px;
  white-space: nowrap; letter-spacing: .04em; text-transform: none;
}
.chat { padding: 16px; display: flex; flex-direction: column; gap: 10px; font-size: 12.5px; background: var(--card); }
.chat .h { font: 500 10.5px/1 var(--display); letter-spacing: .14em; text-transform: uppercase; color: var(--muted); }
.msg { border: 1px solid var(--border); background: var(--bg); border-radius: 9px; padding: 10px 12px; color: var(--muted); }
.msg b { color: var(--text); display: block; margin-bottom: 3px; font: 500 10.5px/1.6 var(--display); letter-spacing: .06em; }
.msg.me { border-color: rgba(180,121,31,.45); background: rgba(180,121,31,.05); }
.step { display: flex; gap: 8px; align-items: baseline; opacity: 0; animation: appear .5s ease forwards; }
.step .st { font: 400 10.5px/1.6 var(--display); color: var(--teal); }
.step.next .st { color: var(--muted); }
.step:nth-child(2) { animation-delay: .5s; }
.step:nth-child(3) { animation-delay: 1.3s; }
.step:nth-child(4) { animation-delay: 2.1s; }
.step:nth-child(5) { animation-delay: 2.9s; }
@keyframes appear { to { opacity: 1; } }
/* A caption, deliberately not the dashed pill that used to sit here: that shape
   read as a control, and the thing it now says is that there is nothing to press.
   Plain muted text, out of the mockup's own chrome — below the agent transcript
   in the hero, below the browser frame in the embed — where it has room to be
   read and cannot be mistaken for part of the machine it describes. */
.illus-note { margin: 14px 0 0; color: var(--muted); font-size: 11.5px; font-style: italic; }
.screen + .illus-note { margin-top: 10px; }

@media (prefers-reduced-motion: reduce) {
  .agent-cursor { animation: none; }
  .step { opacity: 1; animation: none; }
}

/* ── Sections: label column + content column ─────────────────────── */
/* This is the reference's real structural move. Only sections that carry
   their own .kicker get the two-column rhythm — the .split sections keep
   their kicker inside the left half, so forcing a gutter on them would
   leave an empty 190px and a doubled label. */
section { padding: 72px 0; border-top: 1px solid var(--border); }
section:has(> .kicker) {
  display: grid; grid-template-columns: 190px minmax(0, 1fr);
  /* column-gap only. Every child of the content column is its own grid item,
     so a row-gap would stack on top of the margins that already set the
     rhythm between kicker, h2, lede and grid — 44px of it, three times. */
  column-gap: 44px; row-gap: 0; align-items: start;
}
section:has(> .kicker) > * { grid-column: 2; }
section:has(> .kicker) > .kicker { grid-column: 1; grid-row: 1 / -1; }
@media (max-width: 900px) {
  section:has(> .kicker) { grid-template-columns: 1fr; column-gap: 0; }
  section:has(> .kicker) > *, section:has(> .kicker) > .kicker { grid-column: 1; grid-row: auto; }
  section:has(> .kicker) > .kicker { margin-bottom: 12px; }
}
.kicker {
  font: 500 10.5px/1.5 var(--display); letter-spacing: .16em; text-transform: uppercase;
  color: var(--accent-text); margin: 0 0 12px;
}
h2 { font-size: clamp(24px, 3.4vw, 32px); line-height: 1.14; margin: 0 0 14px; }
.sectionlede { color: var(--muted); max-width: 56ch; margin: 0 0 36px; font-size: 16px; }

/* Eight feature cards as one hairline-ruled block rather than eight floating
   boxes: on paper, a grid of bordered cards reads as clutter, while a single
   ruled field reads as a spec sheet. 2 -> 1 columns; the count divides evenly
   either way. */
.grid {
  display: grid; grid-template-columns: repeat(2, 1fr); gap: 1px;
  background: var(--border); border: 1px solid var(--border);
  border-radius: 12px; overflow: hidden;
}
@media (max-width: 640px) { .grid { grid-template-columns: 1fr; } }
.card { background: var(--card); border: 0; border-radius: 0; padding: 22px 24px; }
.card .ico {
  width: auto; height: auto; border-radius: 0; background: none;
  display: block; margin-bottom: 10px; color: var(--green); font-size: 17px; line-height: 1;
}
.card b { display: block; font-size: 15.5px; font-weight: 600; margin-bottom: 6px; }
.card p { margin: 0; color: var(--muted); font-size: 14px; }

/* Not 1fr 1fr. The code column carries the API samples, whose longest lines
   (the TypeScript `const c = await client.computers.create(...)`) must not wrap
   on a marketing page. The prose column gives up the width it does not need. */
.split { display: grid; gap: 44px; grid-template-columns: minmax(0, .86fr) minmax(0, 1.14fr); align-items: center; }
@media (max-width: 820px) { .split { grid-template-columns: minmax(0, 1fr); } }
pre {
  margin: 0; background: var(--term); border: 1px solid var(--term); border-radius: 12px;
  padding: 20px 22px; overflow-x: auto;
  font: 400 13px/1.75 var(--display);
  color: var(--term-fg);
}
.tok-k { color: #9fb8e8; } .tok-s { color: #7fc4a8; } .tok-c { color: #8c887e; } .tok-f { color: #e0b46a; }

/* All examples share one grid cell. JS adds tabs; without it, show each guide. */
#api .split { align-items: start; }
.examples { min-width: 0; }
.example-tabs { display: flex; gap: 4px; border-bottom: 1px solid var(--border); }
.example-tabs[hidden], .example-panel[hidden] { display: none; }
.example-tabs button {
  appearance: none; border: 0; border-bottom: 2px solid transparent;
  background: transparent; color: var(--muted); cursor: pointer;
  padding: 12px 14px; font: 500 13px/1.5 var(--display);
}
.example-tabs button:hover { color: var(--text); background: var(--panel); }
.example-tabs button[aria-selected="true"] { color: var(--text); border-bottom-color: var(--text); }
.example-panel h3 { margin: 28px 0 12px; font-size: 17px; }
.examples.enhanced .example-panel h3 { display: none; }
/* Stand in for the enhanced layout between first paint and the deferred script,
   so the guides do not paint stacked and then snap to one tab. `.js-examples` is
   set inline in <head> and cleared on DOMContentLoaded, so a script that never
   runs — or that bails on a widget it does not recognise — restores every guide
   rather than leaving two hidden. The tablist is deliberately NOT revealed here:
   it stays [hidden] until examples.js has wired it, because a role="tablist"
   with no handlers and panels that are not yet tabpanels is worse for a keyboard
   or screen-reader user than a tab strip that appears a moment later. */
.js-examples .examples:not(.enhanced) .example-panel h3 { display: none; }
.js-examples .examples:not(.enhanced) .example-panel ~ .example-panel { display: none; }
.example-label { margin: 18px 0 8px; font: 400 12px/1.6 var(--display); color: var(--muted); }
.example-note { margin: 14px 0 0; color: var(--muted); font-size: 13px; overflow-wrap: anywhere; }
.example-note code { font-family: var(--display); font-size: .95em; color: var(--text); }
.example-note a { color: var(--text); text-underline-offset: 3px; }
.example-prompt { margin: 18px 0; padding: 16px 20px; border-left: 2px solid var(--green); background: var(--panel); font-size: 15px; }
.checklist { list-style: none; padding: 0; margin: 22px 0 0; }
.checklist li { padding-left: 26px; position: relative; margin-bottom: 12px; color: var(--muted); font-size: 14.5px; }
.checklist li::before { content: "→"; position: absolute; left: 0; top: 0; color: var(--green); font: 400 12.5px/1.6 var(--display); }
.checklist li b { color: var(--text); font-weight: 600; }

/* Small embedded-screen demo */
.screen {
  border: 1px solid var(--border); border-radius: 12px; overflow: hidden;
  background: var(--card); box-shadow: 0 24px 60px -44px rgba(22,21,19,.5);
}
.screen .bar { display: flex; align-items: center; gap: 6px; padding: 10px 14px; background: var(--card); border-bottom: 1px solid var(--border); }
.screen .dot { width: 9px; height: 9px; border-radius: 50%; background: var(--border); }
.screen .addr { margin-left: 10px; flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; background: var(--bg); border: 1px solid var(--border); border-radius: 6px; padding: 3px 10px; font: 400 11.5px/1.7 var(--display); color: var(--muted); }
.screen .body { padding: 18px; min-height: 220px; background: var(--panel); }
.win { background: var(--card); border: 1px solid var(--border); border-radius: 7px; margin-bottom: 12px; overflow: hidden; }
.win .t { padding: 6px 12px; font: 400 11px/1.6 var(--display); color: var(--muted); border-bottom: 1px solid var(--border); }
.win .c { padding: 12px; font: 400 11.5px/1.65 var(--display); color: var(--text); }
.cursor-dot { display: inline-block; width: 11px; height: 11px; border: 2px solid var(--green); border-radius: 50%; vertical-align: middle; margin-left: 6px; }

/* ── Pricing ─────────────────────────────────────────────────────── */
.tiers { display: grid; gap: 12px; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); align-items: stretch; }
.tier { background: var(--card); border: 1px solid var(--border); border-radius: 12px; padding: 24px 22px; display: flex; flex-direction: column; }
.tier.hot { border-color: var(--green); background: var(--card); }
.tier h3 { margin: 0 0 4px; font-size: 15px; letter-spacing: .1em; text-transform: uppercase; color: var(--muted); font-weight: 500; }
.tier .blurb { color: var(--muted); font-size: 13px; margin: 0; }
.tier .tag { font: 500 11px/1 var(--display); color: var(--accent-text); letter-spacing: .08em; text-transform: uppercase; }
.price {
  font-size: 36px; margin: 16px 0 2px;
  font-variant-numeric: tabular-nums;
}
.price span { font: 400 13px/1 var(--body); color: var(--muted); letter-spacing: 0; }
.tier ul { list-style: none; padding: 0; margin: 18px 0 24px; flex: 1; }
.tier li { padding-left: 22px; position: relative; margin-bottom: 9px; color: var(--muted); font-size: 13.5px; }
.tier li::before { content: "✓"; position: absolute; left: 0; color: var(--teal); font-weight: 600; }
.tier .btn { text-align: center; }

.scroll { overflow-x: auto; }
table.compare { border-collapse: collapse; width: 100%; min-width: 640px; font-size: 14px; font-variant-numeric: tabular-nums; }
.compare th, .compare td { text-align: left; padding: 12px 16px; border-bottom: 1px solid var(--border); }
.compare thead th { font: 500 10.5px/1.5 var(--display); letter-spacing: .14em; text-transform: uppercase; color: var(--muted); }
.compare tbody th { color: var(--muted); font-weight: 400; }
.compare tbody tr:last-child > * { border-bottom: none; }

.faq { max-width: 720px; }
.faq details { border-bottom: 1px solid var(--border); padding: 4px 0; }
.faq summary { cursor: pointer; padding: 14px 0; font-weight: 600; font-size: 15px; list-style: none; position: relative; padding-right: 30px; }
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after { content: "+"; position: absolute; right: 4px; color: var(--green); font-size: 18px; font-family: var(--display); }
.faq details[open] summary::after { content: "–"; }
.faq details p { margin: 0 0 16px; color: var(--muted); font-size: 14.5px; max-width: 62ch; }

/* ── Page header (subpages) ──────────────────────────────────────── */
.pagehead { padding: 72px 0 10px; }
.pagehead h1 { font-size: clamp(32px, 5vw, 46px); max-width: 20ch; }
.pagehead .lede { margin-left: 0; max-width: 54ch; }

/* ── Legal prose ─────────────────────────────────────────────────── */
.legal { max-width: 700px; padding: 24px 0 90px; }
.legal h2 { font-size: 19px; margin: 38px 0 10px; }
.legal p, .legal li { color: #46443e; font-size: 15px; }
.legal ul { padding-left: 22px; }
.legal .updated { color: var(--muted); font: 400 13px/1.6 var(--display); }
.legal a { color: var(--accent-text); }

/* ── CTA + footer ────────────────────────────────────────────────── */
.cta { text-align: left; padding: 92px 0; border-top: 1px solid var(--border); }
.cta h2 { font-size: clamp(28px, 4.6vw, 42px); max-width: 18ch; }
.cta .sectionlede { margin: 14px 0 30px; }
footer.site { border-top: 1px solid var(--border); padding: 26px 0; color: var(--muted); font-size: 13px; }
footer.site .inner { display: flex; flex-wrap: wrap; gap: 8px 20px; justify-content: space-between; }
footer.site a { color: var(--muted); }
footer.site a:hover { color: var(--text); }

footer.site .ficons { display: inline-flex; gap: 14px; align-items: center; margin-left: 18px; vertical-align: middle; }
footer.site .ficons a { color: var(--muted); display: inline-flex; }
footer.site .ficons a:hover { color: var(--text); }
footer.site .ficons svg { width: 16px; height: 16px; fill: currentColor; }
