/*
 * The palette is derived from `public/symbol.svg`, the pixel-art saruê face.
 * The symbol uses exactly five colours, and three of them are used here
 * unchanged: black #000, tan #ad8653, white #fff, peach #ffc2a8, grey #afafaf.
 *
 * Two derivations were forced by measured contrast rather than taste:
 *
 * - `--accent` is the peach hue darkened to #8f4a26 (6.34:1 on the page), because
 *   the icon's own tan reaches only 3.19:1 and cannot carry link text.
 * - the peach ground is only 1.49:1 against the page, so it cannot identify a
 *   control on its own. It is kept for soft fills — the trait chips, the focused
 *   skip link — and the primary button is filled with `--accent` instead, with
 *   `--on-accent` as its label colour.
 *
 * The greys are neutral, following the icon, and the warmth lives entirely in
 * the peach and tan accents — the same proportion the animal has.
 *
 * The colours are this site's own; the details are the family's. ColaPIX and
 * ritmun share a set of small conventions — the mark on a rounded tile, the
 * wordmark split in two tones on its dot, a square outlined control at the right
 * of the header, a filled primary button, soft-tinted pill chips, cards with a
 * faint two-layer shadow, muted uppercase section labels, a notice with a full
 * border and a coloured left rule — and this stylesheet follows the same
 * conventions so the three read as one house. What stays distinct is the
 * palette, the typeface and the pixel-art symbol.
 *
 * The typeface is Atkinson Hyperlegible Next, commissioned by the Braille
 * Institute and drawn so that similar characters cannot be confused. It is
 * self-hosted from this domain — no third party is contacted to render a page.
 */

/*
 * Self-hosted, latin subset only, copied out of its Fontsource package by
 * `scripts/build.mjs`. SIL Open Font License 1.1; the text ships at
 * /licenses/atkinson-hyperlegible-next-OFL.txt and the footer links to it.
 */
@font-face {
  font-family: 'Atkinson Hyperlegible Next Variable';
  font-style: normal;
  font-display: swap;
  font-weight: 200 800;
  src: url('/fonts/atkinson-hyperlegible-next-latin-wght-normal.woff2') format('woff2-variations');
  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;
}

:root {
  --paper: #fafafa;
  --surface: #ffffff;
  /* A step below the surface, for a hovered menu row and the switch's track. */
  --surface-sunk: #f0f0f0;
  --ink: #0f0f0f;
  --ink-soft: #575757;
  --line: #e2e2e2;
  --gray: #afafaf;
  --gray-light: #d7d7d7;
  --peach: #ffc2a8;
  --peach-soft: #fff0e9;
  --tan: #ad8653;
  --accent: #8f4a26;
  /* Filled buttons: a darker step for hover, and the label colour on the fill. */
  --accent-hover: #7a3d1e;
  --on-accent: #ffffff;
  /* The ground the pixel-art symbol sits on in the masthead. Light in both
     themes, as on the preview card: the tile frames the mark, so keeping the
     frame light keeps the black outline, where a dark frame would swallow it. */
  --tile: #ffffff;
  --tile-edge: #e2e2e2;
  /* Corner and lift shared with ritmun: 14px on cards and notices, 10px on the
     square header control, and a faint two-layer shadow under raised surfaces. */
  --radius: 14px;
  --radius-control: 10px;
  --shadow: 0 1px 2px rgb(15 15 15 / 6%), 0 8px 24px rgb(15 15 15 / 6%);
  --measure: 62rem;
  --font-body:
    'Atkinson Hyperlegible Next Variable', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  color-scheme: light;
}

/*
 * The dark palette, written twice on purpose.
 *
 * `/theme-init.js` stamps `data-theme` on <html> from the stored choice or the
 * system preference, and the menu switch rewrites it — that is the attribute
 * block. The media-query block is for the reader with JavaScript off, who gets
 * no attribute at all and still deserves a dark page when the system asks for
 * one; the `:not([data-theme='light'])` guard keeps it from overriding an
 * explicit choice of light on a dark system. CSS has no way to say "these two
 * selectors, one of them under a media query" in one rule, so the tokens are
 * repeated, and `test/contrast.test.js` fails if the two blocks ever differ.
 */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) {
    --paper: #121212;
    --surface: #1b1b1b;
    --surface-sunk: #242424;
    --ink: #f2f2f2;
    --ink-soft: #a6a6a6;
    --line: #2d2d2d;
    --gray: #8f8f8f;
    --gray-light: #3a3a3a;
    --peach: #ffc2a8;
    --peach-soft: #2e211c;
    --tan: #c99a67;
    /* On a dark ground the icon's own peach already reaches 12.07:1. */
    --accent: #ffc2a8;
    /* The accent is the light colour here, so hover steps lighter, not darker,
       and the label on the fill is the dark ink. */
    --accent-hover: #ffd3c0;
    --on-accent: #0f0f0f;
    --shadow: 0 1px 2px rgb(0 0 0 / 30%), 0 8px 24px rgb(0 0 0 / 25%);
    color-scheme: dark;
  }
}

:root[data-theme='dark'] {
  --paper: #121212;
  --surface: #1b1b1b;
  --surface-sunk: #242424;
  --ink: #f2f2f2;
  --ink-soft: #a6a6a6;
  --line: #2d2d2d;
  --gray: #8f8f8f;
  --gray-light: #3a3a3a;
  --peach: #ffc2a8;
  --peach-soft: #2e211c;
  --tan: #c99a67;
  /* On a dark ground the icon's own peach already reaches 12.07:1. */
  --accent: #ffc2a8;
  /* The accent is the light colour here, so hover steps lighter, not darker,
     and the label on the fill is the dark ink. */
  --accent-hover: #ffd3c0;
  --on-accent: #0f0f0f;
  --shadow: 0 1px 2px rgb(0 0 0 / 30%), 0 8px 24px rgb(0 0 0 / 25%);
  color-scheme: dark;
}

* {
  box-sizing: border-box;
}

html {
  min-width: 320px;
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font: 16px/1.6 var(--font-body);
  -webkit-text-size-adjust: 100%;
}

a {
  color: var(--accent);
  text-decoration-thickness: 1px;
  text-underline-offset: 2px;
}

/* Off-screen for sighted readers, still in the accessible name and still
   reachable by a screen reader's own cursor. */
.vh {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  border: 0;
  margin: -1px;
  clip-path: inset(50%);
  overflow: hidden;
  white-space: nowrap;
}

/* Parked above the viewport and slid in on focus, the way the apps do it, so
   it never shifts the masthead when it appears. */
.skip {
  position: fixed;
  z-index: 20;
  top: 0.5rem;
  left: 0.5rem;
  padding: 0.6rem 0.9rem;
  border-radius: var(--radius-control);
  /* Peach is light in both themes, so this text is dark in both. Using --ink
     here rendered #f2f2f2 on #ffc2a8 in dark mode: 1.39:1. */
  background: var(--peach);
  color: #0f0f0f;
  font-weight: 650;
  text-decoration: none;
  transform: translateY(-150%);
}

.skip:focus {
  transform: none;
  outline: 2px solid var(--ink);
}

/* Masthead --------------------------------------------------------------- */

.masthead,
main,
.footer {
  max-width: var(--measure);
  margin-inline: auto;
  padding-inline: clamp(1rem, 4vw, 2.5rem);
}

.masthead {
  /* Above <main>, so the dropdown menu can overlap the hero. */
  position: relative;
  z-index: 3;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding-top: 1.5rem;
}

/* The language switch and the menu button, together at the right edge. */
.masthead__actions {
  display: flex;
  flex: none;
  align-items: center;
  gap: 0.5rem;
}

.wordmark {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  color: var(--ink);
  font-size: 1.2rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  text-decoration: none;
}

/* Two tones, split on the dot — "Sarue" in the ink, ".Org" in the accent — the
   way ColaPIX writes "ColaPIX.app" and the preview card writes this name. */
.wordmark__tail {
  color: var(--accent);
}

/* The symbol on its tile. The artwork is authored on a 16px grid and the 2rem
   content box is an exact 2x, so the pixel edges stay sharp; `content-box` keeps
   the padding and the border from eating into that multiple. The corner is the
   22% the app badges use. */
.mark {
  box-sizing: content-box;
  width: 2rem;
  height: 2rem;
  padding: 0.25rem;
  border: 1px solid var(--tile-edge);
  border-radius: 22%;
  background: var(--tile);
}

/* The language switch in the same shape as the menu button beside it: a square
   outlined control that tints with the accent on hover. */
.lang {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 2.5rem;
  min-height: 2.5rem;
  padding: 0 0.75rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-control);
  background: none;
  color: var(--ink-soft);
  font-size: 0.85rem;
  font-weight: 650;
  text-decoration: none;
  transition:
    border-color 160ms ease,
    background 160ms ease,
    color 160ms ease;
}

.lang:hover {
  border-color: var(--accent);
  background: var(--peach-soft);
  color: var(--accent);
}

/* Header menu ------------------------------------------------------------ */

/* A flex box, not a block, only so it has no line box: around an inline-block
   button a block wrapper is three pixels taller than the button in Blink, which
   left this control sitting above the language switch beside it. The panel is
   positioned out of flow, so it is not a flex item. */
.menu {
  position: relative;
  display: flex;
  flex: none;
}

/* Nothing to open it without JavaScript, so the button is not shown until
   `/theme-init.js` has stamped the attribute. The stylesheet, not the script,
   makes that call, so the menu never flashes in and out. */
:root:not([data-theme]) .menu {
  display: none;
}

/* Centred the way the apps centre their menu icon — an inline-block button
   with no line box and a block svg whose margins are worked out from the box —
   rather than with grid on the button, which older WebKit lays out as a plain
   block whatever `display` says. */
.menu__button {
  display: inline-block;
  width: 2.5rem;
  height: 2.5rem;
  padding: 0;
  line-height: 0;
  border: 1px solid var(--line);
  border-radius: var(--radius-control);
  background: none;
  color: var(--ink-soft);
  cursor: pointer;
  transition:
    border-color 160ms ease,
    background 160ms ease,
    color 160ms ease;
}

.menu__button:hover,
.menu__button[aria-expanded='true'] {
  border-color: var(--accent);
  background: var(--peach-soft);
  color: var(--accent);
}

.menu__button svg {
  display: block;
  width: 1.25rem;
  height: 1.25rem;
  /* (2.5rem - 2px border - 1.25rem icon) / 2 */
  margin: calc(0.625rem - 1px) auto;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
}

.menu__panel {
  position: absolute;
  z-index: 15;
  top: calc(100% + 0.5rem);
  right: 0;
  min-width: 15rem;
  padding: 0.35rem;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
  box-shadow: var(--shadow);
  animation: menu-reveal 160ms ease both;
}

@keyframes menu-reveal {
  from {
    opacity: 0;
    transform: translateY(-0.35rem);
  }
}

.menu__item {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  width: 100%;
  padding: 0.6rem 0.65rem;
  border: 0;
  border-radius: var(--radius-control);
  background: none;
  color: var(--ink);
  font: inherit;
  font-size: 0.9rem;
  font-weight: 600;
  text-align: left;
  cursor: pointer;
}

.menu__item:hover {
  background: var(--surface-sunk);
}

.menu__icon {
  flex: none;
  width: 1.1rem;
  height: 1.1rem;
  fill: none;
  stroke: var(--accent);
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.menu__label {
  flex: 1;
}

/* A switch rather than a checkmark: the row is a setting, not a command. */
.menu__switch {
  position: relative;
  flex: none;
  width: 2.1rem;
  height: 1.25rem;
  border-radius: 999px;
  background: var(--surface-sunk);
  box-shadow: inset 0 0 0 1px var(--line);
  transition: background 160ms ease;
}

.menu__switch::after {
  content: '';
  position: absolute;
  top: 0.175rem;
  left: 0.175rem;
  width: 0.9rem;
  height: 0.9rem;
  border-radius: 50%;
  background: var(--surface);
  box-shadow: 0 1px 2px rgb(0 0 0 / 25%);
  transition: transform 160ms ease;
}

.menu__item[aria-checked='true'] .menu__switch {
  background: var(--accent);
  box-shadow: none;
}

.menu__item[aria-checked='true'] .menu__switch::after {
  transform: translateX(0.85rem);
}

/* Hero -------------------------------------------------------------------- */

.hero {
  padding: clamp(3rem, 10vw, 6rem) 0 clamp(2rem, 6vw, 3.5rem);
}

/*
 * A greeting, not a label. The uppercase, wide-tracked treatment this slot used
 * to carry suited a descriptor — "organização de ferramentas digitais" — and
 * turned "buenas vivente?" into shouting, so it is set in its own case at
 * something closer to reading size.
 */
.hero__greeting {
  margin: 0 0 0.7rem;
  color: var(--accent);
  font-size: clamp(1.05rem, 2vw, 1.35rem);
  font-weight: 650;
  letter-spacing: -0.01em;
}

.hero__title {
  max-width: 30ch;
  margin: 0;
  font-size: clamp(2rem, 6.5vw, 3.6rem);
  font-weight: 700;
  letter-spacing: -0.04em;
  line-height: 1.05;
  text-wrap: balance;
}

.hero__lead {
  max-width: 58ch;
  margin: 1.5rem 0 0;
  color: var(--ink-soft);
  font-size: clamp(1rem, 1.6vw, 1.12rem);
}

/* Sections ---------------------------------------------------------------- */

section + section {
  padding-top: clamp(2.5rem, 7vw, 4.5rem);
}

/* The muted uppercase label ritmun heads its blocks with, opened by the short
   rule ColaPIX puts before its eyebrow. The rule is tan: the marker colour. */
.section__title {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin: 0 0 1rem;
  color: var(--ink-soft);
  font-size: 0.78rem;
  font-weight: 650;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.section__title::before {
  flex: none;
  width: 1.4rem;
  height: 2px;
  border-radius: 999px;
  background: var(--tan);
  content: '';
}

.section__intro {
  max-width: 52ch;
  margin: 0 0 1.5rem;
  color: var(--ink-soft);
}

/* Branches ---------------------------------------------------------------- */

.branches__grid {
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 18rem), 1fr));
}

/* A notice, in the shape the apps give theirs: a full hairline border, a
   coloured rule on the left, and the shared corner. */
.branch {
  padding: 1.25rem 1.25rem 1.4rem;
  border: 1px solid var(--line);
  border-left: 3px solid var(--tan);
  border-radius: var(--radius);
  background: var(--surface);
}

.branch h3 {
  margin: 0 0 0.4rem;
  font-size: 1.05rem;
  letter-spacing: -0.01em;
}

.branch p {
  margin: 0;
  color: var(--ink-soft);
  font-size: 0.95rem;
}

/* App grid ---------------------------------------------------------------- */

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

.card {
  display: flex;
  flex-direction: column;
  padding: 1.4rem;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
  box-shadow: var(--shadow);
  transition: border-color 160ms ease;
}

.card:hover {
  border-color: var(--tan);
}

/* An app's logo keeps its own brand colours, so it is never re-tinted by the
   theme. Rounded to match the square badges the apps themselves use. */
.app-icon {
  flex: none;
  border-radius: 22%;
}

.card__name {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin: 0 0 0.4rem;
  font-size: 1.25rem;
  font-weight: 700;
  letter-spacing: -0.02em;
}

.card__tagline {
  margin: 0 0 1rem;
  color: var(--ink-soft);
}

.card__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin: auto 0 0;
  padding-top: 1rem;
}

/* Traits ------------------------------------------------------------------ */

.traits {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin: 0 0 0.25rem;
  padding: 0;
  list-style: none;
}

/* The apps' accent chip: a soft tint carrying the accent as text, no border. */
.traits li {
  display: inline-flex;
  align-items: center;
  padding: 0.15rem 0.6rem;
  border-radius: 999px;
  background: var(--peach-soft);
  color: var(--accent);
  font-size: 0.78rem;
  font-weight: 650;
  letter-spacing: 0.01em;
}

/* Buttons ----------------------------------------------------------------- */

.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  min-height: 2.5rem;
  padding: 0.5rem 1.1rem;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--surface);
  color: var(--ink);
  font-size: 0.92rem;
  font-weight: 600;
  text-align: center;
  text-decoration: none;
  /* Colour too, so a theme switch never leaves old text on a new background. */
  transition:
    border-color 160ms ease,
    background 160ms ease,
    color 160ms ease,
    transform 120ms ease;
}

.button:hover {
  border-color: var(--accent);
  color: var(--accent);
}

.button:active {
  transform: translateY(1px);
}

/* Filled with the accent, as the apps fill theirs. The fill itself is the
   boundary, at the same 3:1 the accent already clears against the page. */
.button--primary {
  border-color: var(--accent);
  background: var(--accent);
  color: var(--on-accent);
}

.button--primary:hover {
  border-color: var(--accent-hover);
  background: var(--accent-hover);
  color: var(--on-accent);
}

.button--wide {
  display: flex;
  width: 100%;
  margin-bottom: 0.5rem;
}

/* Principles -------------------------------------------------------------- */

.principles__list {
  max-width: 60ch;
  margin: 0;
  padding: 0;
  list-style: none;
}

.principles__list li {
  position: relative;
  padding: 0.55rem 0 0.55rem 1.6rem;
  border-bottom: 1px solid var(--line);
  color: var(--ink-soft);
}

.principles__list li::before {
  position: absolute;
  top: 1.15rem;
  left: 0.15rem;
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 999px;
  background: var(--tan);
  content: '';
}

/* Detail page ------------------------------------------------------------- */

.crumbs {
  padding-top: 2rem;
  font-size: 0.9rem;
}

/* A text button, as in the apps: weight instead of an underline at rest. */
.crumbs a {
  font-weight: 650;
  text-decoration: none;
}

.crumbs a:hover {
  text-decoration: underline;
}

.detail__head {
  padding: 1.5rem 0 2rem;
  border-bottom: 1px solid var(--line);
  grid-column: 1 / -1;
}

.detail__name {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin: 0 0 0.5rem;
  font-size: clamp(1.9rem, 5.5vw, 2.75rem);
  font-weight: 700;
  letter-spacing: -0.04em;
  line-height: 1.1;
}

.detail__tagline {
  max-width: 46ch;
  margin: 0 0 1rem;
  color: var(--ink-soft);
  font-size: clamp(1.02rem, 2vw, 1.2rem);
}

.detail {
  display: grid;
  gap: clamp(1.5rem, 4vw, 3rem);
  padding-bottom: 3rem;
  grid-template-columns: 1fr;
}

@media (min-width: 52rem) {
  .detail {
    grid-template-columns: minmax(0, 1fr) 17rem;
  }
}

.detail__body p {
  max-width: 62ch;
  color: var(--ink-soft);
}

.detail__body .section__title {
  margin-top: 2rem;
}

.highlights {
  max-width: 60ch;
  margin: 0;
  padding: 0;
  list-style: none;
}

.highlights li {
  position: relative;
  padding: 0.5rem 0 0.5rem 1.6rem;
  color: var(--ink-soft);
}

.highlights li::before {
  position: absolute;
  top: 1.05rem;
  left: 0.15rem;
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 999px;
  background: var(--tan);
  content: '';
}

.detail__aside {
  align-self: start;
  padding: 1.25rem;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
  box-shadow: var(--shadow);
}

.detail__meta {
  margin: 0.75rem 0 0;
  color: var(--ink-soft);
  font-size: 0.85rem;
}

/* Footer ------------------------------------------------------------------ */

.footer {
  margin-top: clamp(3rem, 8vw, 5rem);
  padding-block: 2rem;
  border-top: 1px solid var(--line);
  color: var(--ink-soft);
  font-size: 0.85rem;
}

.footer p {
  margin: 0;
}

.footer p + p {
  margin-top: 0.4rem;
}

.footer__credit {
  max-width: 44ch;
  color: var(--ink-soft);
  font-size: 0.8rem;
}

/* Terms page -------------------------------------------------------------- */

.terms {
  max-width: 44rem;
  padding-bottom: 3rem;
}

.terms__head {
  padding: 1.5rem 0 1.75rem;
  border-bottom: 1px solid var(--line);
}

.terms__updated {
  margin: 0;
  color: var(--ink-soft);
  font-size: 0.85rem;
}

.terms__body {
  padding-top: 1.5rem;
}

.terms__body h2 {
  margin: 2rem 0 0.5rem;
  font-size: 1.02rem;
}

.terms__body p {
  color: var(--ink-soft);
}

.terms__body code {
  padding: 0.05rem 0.3rem;
  border-radius: 5px;
  background: var(--surface);
  font-size: 0.92em;
}

/* The liability section is the one a reader most needs to notice: the same
   notice shape as `.branch`, which both apps use for the clauses that limit
   the reader's rights. */
.terms__emphasis {
  padding: 0.9rem 1rem;
  border: 1px solid var(--line);
  border-left: 3px solid var(--tan);
  border-radius: var(--radius);
  background: var(--surface);
}

/* Global: focus and motion ------------------------------------------------ */

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

/* On the one control filled with the accent the ring would only echo the fill
   across the 2px gap. --ink reads against the gap in both themes. */
.button--primary:focus-visible {
  outline-color: var(--ink);
}

/* Focus must stay visible on the skip target even though it is not a control. */
main:focus {
  outline: none;
}

/* Windows high-contrast mode drops backgrounds, so the switch is redrawn
   with system colours, as the apps do. */
@media (forced-colors: active) {
  .menu__switch {
    forced-color-adjust: none;
    background: Canvas;
    outline: 1px solid CanvasText;
  }

  .menu__switch::after {
    background: CanvasText;
  }

  .menu__item[aria-checked='true'] .menu__switch {
    background: Highlight;
  }

  .menu__item[aria-checked='true'] .menu__switch::after {
    background: HighlightText;
  }
}

@media (prefers-reduced-motion: reduce) {
  * {
    transition-duration: 0ms !important;
    animation-duration: 0ms !important;
  }
}
