/* ==========================================================================
   theysap. shared styles
   Palette and layout rhythm follow tode.sh: hairline borders, square corners,
   small type, a 64px left gutter on wide screens.
   ========================================================================== */

/* Faculty Glyphic, under the SIL Open Font License 1.1. See assets/fonts/OFL.txt.
   Self-hosted so the site makes no third-party requests at all. */

@font-face {
  font-family: "Faculty Glyphic";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/assets/fonts/faculty-glyphic-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: "Faculty Glyphic";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/assets/fonts/faculty-glyphic-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 {
  color-scheme: light dark;

  --bg: #fbfbfa;
  --panel: #f4f4f2;
  --panel2: #eeeeec;
  --border: #dededa;
  --border-soft: #e8e8e4;
  --text: #17171a;
  --text2: #45454c;
  --muted: #74747d;
  --faint: #9a9aa2;
  --ok: #418321;
  --line: #00000012;

  /* Neon blue and red, for the home page's Explore buttons. */
  --blue: #0b6fd8;
  --red: #d42a3c;

  /* Lavender, for the note that explains the Gatekeeper warning. */
  --lav: #5f4fb8;
  --lav-bg: #f4f2fb;
  --lav-border: #dcd5f2;

  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
  --maxw: 880px;
  --gutter: 64px;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #0c0c0d;
    --panel: #121214;
    --panel2: #17171a;
    --border: #26262a;
    --border-soft: #1e1e21;
    --text: #ededf0;
    --text2: #b8b8c0;
    --muted: #82828c;
    --faint: #5a5a63;
    --ok: #6ad734;
    --line: #ffffff0e;
    --blue: #3dbbff;
    --red: #ff4058;
    --lav: #b9a9f5;
    --lav-bg: #17142a;
    --lav-border: #322b52;
  }
}

:root[data-theme="dark"] {
  --bg: #0c0c0d;
  --panel: #121214;
  --panel2: #17171a;
  --border: #26262a;
  --border-soft: #1e1e21;
  --text: #ededf0;
  --text2: #b8b8c0;
  --muted: #82828c;
  --faint: #5a5a63;
  --ok: #6ad734;
  --line: #ffffff0e;
  --blue: #3dbbff;
  --red: #ff4058;
  --lav: #b9a9f5;
  --lav-bg: #17142a;
  --lav-border: #322b52;
}

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  background: var(--bg);
  color: var(--text);
  font-family: "Faculty Glyphic", ui-sans-serif, system-ui, -apple-system, sans-serif;
  /* Faculty Glyphic ships weight 400 only, so never let the browser fake a bold. */
  font-synthesis: none;
  font-size: 14px;
  line-height: 22px;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}

a { color: inherit; text-decoration: none; }

:focus-visible { outline: 1px solid var(--ok); outline-offset: 2px; }

h1, h2, h3, p, ul, ol, figure { margin: 0; }

code, pre, .mono { font-family: var(--mono); }

/* --- shell ---------------------------------------------------------------- */

.wrap {
  width: 100%;
  max-width: var(--maxw);
  margin-inline: auto;
  padding-inline: 20px;
}

@media (min-width: 640px) {
  .wrap { padding-inline: 32px; }
}

/* Sticky footer: main fills the leftover viewport height, and an ordered
   spacer absorbs it so the footer lands at the bottom on short pages while
   keeping its normal margin on long ones. */
main.wrap {
  flex: 1;
  display: flex;
  flex-direction: column;
}

main.wrap > * { flex: none; }

main.wrap::after {
  content: "";
  flex: 1 1 auto;
  order: 1;
}

main.wrap > .site-footer { order: 2; }

/* Full-bleed hairline that sits on top of whatever follows it. */
.rule { position: relative; }
.rule::before {
  content: "";
  position: absolute;
  top: 0;
  left: 50%;
  width: 100vw;
  height: 1px;
  margin-left: -50vw;
  background: var(--line);
}

/* Two-column reading grid: an empty 64px gutter, then the content. */
.row {
  display: grid;
  grid-template-columns: 1fr;
  gap: 32px;
}

.row > .gutter { display: none; }

@media (min-width: 640px) {
  .row { grid-template-columns: var(--gutter) 1fr; }
  .row > .gutter { display: block; }
}

.row > .col { min-width: 0; }

/* --- header --------------------------------------------------------------- */

.site-header { border-bottom: 1px solid var(--border-soft); }

.site-header .wrap {
  height: 52px;
  display: flex;
  align-items: center;
  justify-content: space-between;
}

/* The wordmark, set in the same face as the logo artwork. */
.wordmark {
  display: inline-flex;
  align-items: baseline;
  font-size: 18px;
  line-height: 1;
  letter-spacing: -0.015em;
  color: var(--text);
  transition: opacity 0.15s;
}

.wordmark:hover { opacity: 0.7; }

/* The wordmark's period is part of the logo, not an accent, so keep it on-colour. */
.wordmark .dot { color: inherit; }

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

.social a {
  display: grid;
  place-items: center;
  width: 22px;
  height: 22px;
  color: var(--faint);
  transition: color 0.15s;
}

.social a:hover { color: var(--text); }

/* --- hero ----------------------------------------------------------------- */

.hero { padding-block: 64px; }

@media (min-width: 640px) {
  .hero { padding-block: 96px; }
}

h1 {
  font-size: 20px;
  line-height: 1.22;
  letter-spacing: -0.02em;
  color: var(--text);
}

@media (min-width: 640px) {
  h1 { font-size: 26px; }
}

/* Boxed word, borrowed from the tode.sh headline treatment. */
.keyword {
  font-family: var(--mono);
  font-size: 0.9em;
  letter-spacing: -0.01em;
  white-space: nowrap;
  padding: 2px 7px;
  border: 1px solid var(--border);
  background: var(--panel2);
}

.caret {
  display: inline-block;
  width: 0.5em;
  height: 1.05em;
  margin-left: 0.19em;
  vertical-align: -0.16em;
  background: var(--ok);
  animation: caret-blink 1.06s step-end infinite;
}

@keyframes caret-blink { 0%, 100% { opacity: 1; } 50% { opacity: 0; } }

@media (prefers-reduced-motion: reduce) {
  .caret { animation: none; }
}

.lede {
  margin-top: 18px;
  font-size: 13.5px;
  line-height: 21px;
  color: var(--muted);
}

/* Only the hero gets the tight measure; section intros read better full width. */
.hero .lede { max-width: 46ch; }

/* --- section scaffolding -------------------------------------------------- */

.section { padding-block: 48px; }

@media (min-width: 640px) {
  .section { padding-block: 56px; }
}

.eyebrow {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--faint);
}

/* On wide screens the eyebrow sits in the left gutter, level with the content. */
@media (min-width: 640px) {
  .row > .gutter .eyebrow { display: block; padding-top: 3px; }
}

h2 {
  font-size: 16px;
  line-height: 1.3;
  letter-spacing: -0.015em;
  color: var(--text);
}

h3 {
  font-size: 13.5px;
  line-height: 1.4;
  letter-spacing: -0.01em;
  color: var(--text2);
}

.prose p {
  font-size: 13.5px;
  line-height: 22px;
  color: var(--muted);
}

.prose p + p { margin-top: 12px; }

.prose strong { color: var(--text2); font-weight: inherit; }

a.link {
  color: var(--text2);
  border-bottom: 1px solid var(--muted);
  transition: color 0.15s, border-color 0.15s;
}

a.link:hover { color: var(--text); border-bottom-color: currentColor; }

/* --- home page -------------------------------------------------------------- */

/* The home page shows two apps and two extensions in one section. It keeps
   the full hero, but takes tighter section spacing than the other pages and
   lets the sticky footer's spacer stand in for its top margin, so the footer
   stays on screen without scrolling. */
.home .section { padding-block: 40px; }
.home .site-footer { margin-top: 0; }

@media (min-width: 640px) {
  .home .card { min-height: 148px; }
}

/* "Explore all", under each group of cards on the home page. */
.more { margin-top: 14px; }

.btn.small {
  gap: 7px;
  height: 30px;
  padding: 0 12px;
  font-size: 12px;
}

.btn.small svg { transition: transform 0.15s; }
.btn.small:hover svg { transform: translateX(2px); }

/* --- app cards ------------------------------------------------------------ */

.cards {
  display: grid;
  grid-template-columns: 1fr;
  gap: 14px;
}

@media (min-width: 640px) {
  .cards { grid-template-columns: 1fr 1fr; }
  /* Level the cards only once they sit side by side. */
  .card { min-height: 168px; }
}

.card {
  display: flex;
  flex-direction: column;
  padding: 16px;
  border: 1px solid var(--border);
  background: var(--panel);
  transition: border-color 0.15s, background-color 0.15s;
}

a.card:hover {
  border-color: var(--muted);
  background: var(--panel2);
}

a.card:hover .card-go { color: var(--text); transform: translateX(2px); }

.card-top {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
}

.card-name {
  font-size: 15px;
  letter-spacing: -0.015em;
  color: var(--text);
}

.card-go {
  flex: none;
  color: var(--faint);
  transition: color 0.15s, transform 0.15s;
}

.card-desc {
  margin-top: 8px;
  font-size: 12.5px;
  line-height: 19px;
  color: var(--muted);
}

.card-foot {
  margin-top: auto;
  padding-top: 16px;
  display: flex;
  align-items: center;
  gap: 8px;
  font-family: var(--mono);
  font-size: 11px;
  color: var(--faint);
}

.card-foot .sep { opacity: 0.55; }

/* Greyed-out card for an app that is not shipping yet. */
.card.is-soon {
  background: transparent;
  border-style: dashed;
  cursor: default;
}

.card.is-soon .card-name,
.card.is-soon .card-desc { color: var(--faint); }

.badge {
  font-family: var(--mono);
  font-size: 10.5px;
  line-height: 1;
  padding: 4px 6px;
  border: 1px solid var(--border);
  color: var(--muted);
}


/* --- command box ---------------------------------------------------------- */

.cmd {
  display: flex;
  align-items: center;
  min-height: 38px;
  max-width: 100%;
  padding: 0 10px 0 14px;
  border: 1px solid var(--border);
  background: var(--panel);
}

.cmd .prompt { margin-right: 9px; color: var(--ok); font-family: var(--mono); font-size: 12px; }

.cmd code {
  flex: 1;
  overflow-x: auto;
  white-space: nowrap;
  font-size: 11px;
  color: var(--text2);
  scrollbar-width: none;
}

.cmd code::-webkit-scrollbar { display: none; }

@media (min-width: 640px) {
  .cmd code { font-size: 12px; }
}

.copy {
  flex: none;
  margin-left: 10px;
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  padding: 0;
  border: 1px solid transparent;
  background: none;
  color: color-mix(in srgb, var(--ok) 65%, transparent);
  cursor: pointer;
  transition: color 0.15s, border-color 0.15s;
}

.copy:hover {
  color: var(--ok);
  border-color: color-mix(in srgb, var(--ok) 35%, transparent);
}

.cmd.is-soon { opacity: 0.5; }
.cmd.is-soon .prompt { color: var(--faint); }

/* Confirmation after the copy button is pressed. Positioned over the right
   end of the box, on the box's own background, so the command underneath does
   not reflow when it appears. */
.cmd { position: relative; }

.copied {
  position: absolute;
  top: 50%;
  right: 44px;
  transform: translateY(-50%);
  /* Fades the command out underneath instead of chopping it mid-word. */
  padding-left: 30px;
  background: linear-gradient(to right, transparent, var(--panel) 22px);
  font-family: var(--mono);
  font-size: 11px;
  color: var(--ok);
  opacity: 0;
  transition: opacity 0.12s;
  pointer-events: none;
}

.cmd.is-copied .copied { opacity: 1; }
.cmd.is-copied .copy { color: var(--ok); border-color: color-mix(in srgb, var(--ok) 35%, transparent); }

/* --- definition rows (feature / spec lists) -------------------------------- */

.rows {
  border-top: 1px solid var(--border-soft);
  border-bottom: 1px solid var(--border-soft);
}

.rows > .r {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding-block: 10px;
  border-top: 1px solid var(--border-soft);
}

.rows > .r:first-child { border-top: 0; }

@media (min-width: 640px) {
  .rows > .r { flex-direction: row; align-items: baseline; gap: 24px; }
  .rows > .r > .k { width: 200px; flex: none; }
}

.rows .k {
  font-family: var(--mono);
  font-size: 12px;
  color: var(--text2);
}

.rows .k .accent { color: var(--ok); }

.rows .v { font-size: 12.5px; line-height: 20px; color: var(--muted); }

/* --- numbered steps -------------------------------------------------------- */

.steps { list-style: none; padding: 0; counter-reset: step; }

.steps > li {
  counter-increment: step;
  position: relative;
  padding-left: 26px;
  font-size: 13px;
  line-height: 21px;
  color: var(--muted);
}

.steps > li + li { margin-top: 10px; }

.steps > li::before {
  content: counter(step);
  position: absolute;
  left: 0;
  top: 0;
  font-family: var(--mono);
  font-size: 11px;
  line-height: 21px;
  color: var(--faint);
}

.bullets { list-style: none; padding: 0; }

.bullets > li {
  position: relative;
  padding-left: 16px;
  font-size: 13px;
  line-height: 21px;
  color: var(--muted);
}

.bullets > li + li { margin-top: 6px; }

.bullets > li::before {
  content: "";
  position: absolute;
  left: 2px;
  top: 9px;
  width: 4px;
  height: 4px;
  background: var(--faint);
}

/* --- callout --------------------------------------------------------------- */

.note {
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-left-width: 2px;
  border-left-color: var(--muted);
  background: var(--panel);
  font-size: 12.5px;
  line-height: 20px;
  color: var(--muted);
}

/* The reassurance note. Same shape as .note, lavender so it reads as an
   explanation rather than another warning. */
.note.trust {
  padding: 16px 18px;
  border-color: var(--lav-border);
  border-left-color: var(--lav);
  background: var(--lav-bg);
  color: var(--text2);
}

.note-title {
  display: block;
  margin-bottom: 10px;
  font-size: 13.5px;
  letter-spacing: -0.01em;
  color: var(--lav);
}

.note.trust .bullets > li {
  font-size: 12.5px;
  line-height: 20px;
  color: var(--text2);
}

.note.trust .bullets > li::before { background: var(--lav); }

.note.trust .caveat {
  display: block;
  margin-top: 12px;
  padding-top: 11px;
  border-top: 1px solid var(--lav-border);
  color: var(--muted);
}

.note.trust a.link { color: var(--lav); border-bottom-color: var(--lav-border); }
.note.trust a.link:hover { border-bottom-color: var(--lav); }

/* --- buttons --------------------------------------------------------------- */

.actions { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }

/* The install command and the download button, side by side with the word
   that joins them. The box takes the slack; below ~640px the whole thing
   stacks and "or" sits on its own line between the two. */
.install-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
  margin-top: 26px;
}

/* 520px fits the whole command without it scrolling under the copy button, so
   that is the flex basis too: when the row cannot hold 520px plus the button,
   the pair below wraps to its own line rather than the command truncating. */
.install-row .cmd { flex: 1 1 520px; min-width: 0; max-width: 520px; }

/* One unit, so the word and the button wrap together or not at all. */
.install-row .alt {
  flex: none;
  display: flex;
  align-items: center;
  gap: 12px;
}

.or {
  flex: none;
  font-size: 12.5px;
  color: var(--faint);
}

@media (max-width: 639px) {
  .install-row { flex-direction: column; align-items: stretch; gap: 10px; }
  .install-row .alt { flex-direction: column; align-items: stretch; gap: 10px; }
  /* In a column the basis above would be read as a height, giving a 520px
     tall command box. */
  .install-row .cmd { flex: none; max-width: none; }
  .or { text-align: center; }
}

.btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 38px;
  padding: 0 16px;
  border: 1px solid var(--border);
  background: var(--panel);
  color: var(--text2);
  font-size: 13px;
  letter-spacing: -0.01em;
  transition: border-color 0.15s, color 0.15s, background-color 0.15s;
}

.btn:hover { border-color: var(--muted); color: var(--text); background: var(--panel2); }

/* Green by default. .blue and .red swap the tint and keep everything else. */
.btn.primary {
  --tint: var(--ok);
  border-color: color-mix(in srgb, var(--tint) 45%, transparent);
  color: var(--tint);
  background: color-mix(in srgb, var(--tint) 7%, transparent);
}

.btn.primary:hover {
  border-color: var(--tint);
  background: color-mix(in srgb, var(--tint) 13%, transparent);
}

.btn.primary.blue { --tint: var(--blue); }
.btn.primary.red { --tint: var(--red); }

/* Dormant button for something not shipping yet: a span, not a link. */
.btn.is-soon,
.btn.is-soon:hover {
  border-style: dashed;
  border-color: var(--border);
  background: transparent;
  color: var(--faint);
  cursor: default;
}


/* --- back link -------------------------------------------------------------- */

.back {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-family: var(--mono);
  font-size: 11px;
  color: var(--faint);
  transition: color 0.15s;
}

.back:hover { color: var(--text2); }

/* --- footer ---------------------------------------------------------------- */

.site-footer {
  margin-top: 56px;
  padding-block: 32px;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

@media (min-width: 640px) {
  .site-footer { margin-top: 80px; }
}

.site-footer .copy-line,
.site-footer a {
  font-family: var(--mono);
  font-size: 11px;
  color: var(--faint);
}

.site-footer a { transition: color 0.15s; }
.site-footer a:hover { color: var(--text2); }

.site-footer nav { display: flex; align-items: center; gap: 20px; }

/* --- legal pages ------------------------------------------------------------ */

/* Every legal page opens with an intro paragraph, so the first h2 needs its
   top margin like all the others. */
.legal h2 { margin-top: 34px; }
.legal h2 + p { margin-top: 10px; }
.legal .updated {
  font-family: var(--mono);
  font-size: 11px;
  color: var(--faint);
}

.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}
