/* A language learner's notebook: graph paper, a red margin line, yellow highlighter.
   Colours, fonts and both themes come from packages/design-tokens (served as /tokens.css, loaded
   first). Use only its names here; a raw colour would stay the same in dark mode. */

/* Self-hosted from packages/design-tokens/fonts (OFL, licences beside them), copied to /fonts by
   the build; the extension uses the same files. Each file name
   is its content for good: a changed font gets a new name, or Cloudflare serves the old one. */
@font-face {
  font-family: "Young Serif";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/fonts/young-serif-latin-400-normal.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: "Young Serif";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/fonts/young-serif-latin-ext-400-normal.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: "Schibsted Grotesk";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/fonts/schibsted-grotesk-latin-400-normal.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: "Schibsted Grotesk";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/fonts/schibsted-grotesk-latin-ext-400-normal.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: "Schibsted Grotesk";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("/fonts/schibsted-grotesk-latin-500-normal.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: "Schibsted Grotesk";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("/fonts/schibsted-grotesk-latin-ext-500-normal.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: "Schibsted Grotesk";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("/fonts/schibsted-grotesk-latin-600-normal.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: "Schibsted Grotesk";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("/fonts/schibsted-grotesk-latin-ext-600-normal.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: "Schibsted Grotesk";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("/fonts/schibsted-grotesk-latin-700-normal.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: "Schibsted Grotesk";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("/fonts/schibsted-grotesk-latin-ext-700-normal.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: "JetBrains Mono";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/fonts/jetbrains-mono-latin-400-normal.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: "JetBrains Mono";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/fonts/jetbrains-mono-latin-ext-400-normal.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: "JetBrains Mono";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("/fonts/jetbrains-mono-latin-500-normal.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: "JetBrains Mono";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("/fonts/jetbrains-mono-latin-ext-500-normal.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;
}

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  color: var(--ink);
  font-family: var(--sans);
  background-color: var(--paper);
  background-image:
    linear-gradient(var(--grid-line) 1px, transparent 1px),
    linear-gradient(90deg, var(--grid-line) 1px, transparent 1px);
  background-size: var(--grid-page) var(--grid-page);
}

h1,
h2 {
  margin: 0;
  font-family: var(--serif);
  font-weight: 400;
}

p {
  margin: 0;
}

a {
  color: var(--blue);
}

a:hover {
  color: var(--ink);
}

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

/* Motion: the strong ease-out for UI that enters and leaves (Emil Kowalski's, from his animate
   skill); built-in ease-out is too weak. */
:root {
  --ease-out: cubic-bezier(0.23, 1, 0.32, 1);
}

/* Text helpers */

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

.label {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.08em;
  color: var(--ink-3);
}

.muted {
  font-size: 14px;
  color: var(--ink-3);
}

.lede {
  font-size: 16px;
  line-height: 1.5;
  color: var(--ink-2);
  text-wrap: pretty;
}

.small {
  font-size: 12px;
}

.strong {
  font-weight: 600;
}

.accent {
  color: var(--blue);
}

.ink {
  color: var(--ink);
}

.tap {
  display: flex;
  align-items: center;
  min-height: 44px;
  font-size: 14px;
}

/* Shell: a fixed-width sidebar that stays in view while the main column scrolls. On narrow screens
   it sits above the main column instead (see the media query below). */

.app {
  display: flex;
  min-height: 100vh;
}

.sidebar {
  position: sticky;
  top: 0;
  align-self: flex-start;
  flex: 0 0 248px;
  height: 100vh;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 36px;
  padding: 32px 20px;
  border-right: 1px solid var(--margin-red);
  background: color-mix(in srgb, var(--paper) 82%, transparent);
}

.logo {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  color: var(--ink);
  text-decoration: none;
}

.logo-mark {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  border: 1.5px solid var(--ink);
  border-radius: 6px;
  background: var(--sheet);
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: -0.02em;
  transform: rotate(-3deg);
}

.logo-name {
  font-family: var(--serif);
  font-size: 19px;
  line-height: 1.1;
}

.sidebar ul {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.sidebar li a {
  display: flex;
  gap: 12px;
  align-items: center;
  min-height: 44px;
  padding: 0 10px;
  color: var(--ink);
  font-size: 15px;
  font-weight: 500;
  text-decoration: none;
}

.sidebar li a[aria-current="page"] {
  font-weight: 600;
}

.nav-label {
  padding: 0 3px;
}

.sidebar li a[aria-current="page"] .nav-label {
  background: linear-gradient(180deg, transparent 52%, var(--highlight) 52%);
}

.num {
  font-family: var(--mono);
  font-size: 11px;
  color: var(--ink-3);
}

.sidebar-foot {
  display: flex;
  flex-direction: column;
  gap: 16px;
  margin-top: auto;
}

.plan-short,
.main-foot {
  display: none;
}

.legal {
  color: var(--ink-3);
}

.legal-link {
  color: var(--ink-3);
}

.legal-link:hover {
  color: var(--ink);
}

/* The footer's Swiss flag (Flag.elm): "Built with Elm in Switzerland" when pointed at; pressed,
   a password field in its place; once let in, the commit next to it. */
.flag-spot {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  vertical-align: -2px;
}

.flag-button {
  position: relative;
  display: inline-grid;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  line-height: 0;
}

span.flag-button {
  cursor: default;
}

.flag-button:focus-visible {
  border-radius: 2px;
  outline: 2px solid var(--blue);
  outline-offset: 2px;
}

.flag-art {
  display: block;
  font-size: 13px;
  line-height: 1;
  transform-origin: 15% 100%;
  transition: transform 200ms cubic-bezier(0.2, 0.8, 0.2, 1);
}

/* Its tooltip. */
.flag-button::after {
  position: absolute;
  bottom: calc(100% + 8px);
  left: 50%;
  z-index: 20;
  width: max-content;
  padding: 5px 9px;
  border-radius: var(--radius-popover);
  background: var(--ink);
  color: var(--paper);
  content: attr(data-tip);
  font-size: 12px;
  line-height: 1.3;
  opacity: 0;
  pointer-events: none;
  transform: translate(-50%, 3px);
  transition:
    opacity 150ms ease-out,
    transform 150ms ease-out,
    visibility 150ms;
  visibility: hidden;
}

.flag-button:hover::after,
.flag-button:focus-visible::after {
  opacity: 1;
  transform: translate(-50%, 0);
  visibility: visible;
}

.flag-form {
  display: inline-flex;
  animation: flag-open 160ms ease-out;
}

.flag-field {
  width: 15ch;
  padding: 0 0 1px;
  border: 0;
  border-bottom: 1px dashed var(--line-3);
  background: transparent;
  color: var(--ink);
  font-size: 11px;
}

.flag-field::placeholder {
  color: var(--ink-3);
}

.flag-field:focus {
  border-bottom-color: var(--blue);
  outline: none;
}

@keyframes flag-open {
  from {
    opacity: 0;
    transform: translateX(-4px);
  }
}

/* A wrong password: a small head shake (two names, so each miss plays it again). */
.flag-nope-a {
  animation: flag-nope-a 300ms ease-out;
}

.flag-nope-b {
  animation: flag-nope-b 300ms ease-out;
}

@keyframes flag-nope-a {
  25% {
    transform: translateX(-4px);
  }

  50% {
    transform: translateX(3px);
  }

  75% {
    transform: translateX(-2px);
  }
}

@keyframes flag-nope-b {
  25% {
    transform: translateX(-4px);
  }

  50% {
    transform: translateX(3px);
  }

  75% {
    transform: translateX(-2px);
  }
}

/* Let in: the flag waves, once. */
.flag-wave .flag-art {
  animation: flag-wave 700ms ease-in-out;
}

/* Pointed at, it tilts a little. */
@media (prefers-reduced-motion: no-preference) {
  button.flag-button:hover .flag-art {
    transform: rotate(-8deg) scale(1.08);
  }
}

@keyframes flag-wave {
  25% {
    transform: rotate(-12deg);
  }

  55% {
    transform: rotate(9deg);
  }

  80% {
    transform: rotate(-4deg);
  }
}

.flag-commit {
  font-size: 11px;
  animation: flag-reveal 400ms ease-out;
}

@keyframes flag-reveal {
  from {
    opacity: 0;
    transform: translateX(-4px);
  }
}

@media (prefers-reduced-motion: reduce) {
  .flag-form,
  .flag-nope-a,
  .flag-nope-b,
  .flag-wave .flag-art,
  .flag-commit {
    animation: none;
  }

  .flag-button::after {
    transition: none;
  }
}

.plan-card {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 14px 16px;
  border: 1px dashed color-mix(in srgb, var(--blue) 55%, transparent);
  border-radius: 4px;
  background: var(--sheet);
  color: var(--ink);
  font-size: 14px;
  text-decoration: none;
}

.plan-card .label {
  text-transform: uppercase;
}

.user-chip {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  color: var(--ink);
  font-size: 14px;
  text-decoration: none;
}

.avatar {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: var(--ink);
  color: var(--paper);
  font-family: var(--serif);
  font-size: 15px;
}

.user-text {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.main {
  flex: 1 1 0;
  min-width: 0;
  max-width: 1100px;
  padding: 48px clamp(20px, 4vw, 64px) 72px;
}

.page {
  display: flex;
  flex-direction: column;
  gap: 44px;
}

/* Overview: greeting */

.greeting {
  display: flex;
  flex-wrap: wrap;
  gap: 20px 32px;
  align-items: flex-end;
  justify-content: space-between;
}

.greeting-text {
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-width: 0;
}

.greeting .label {
  font-size: 12px;
  letter-spacing: 0.06em;
}

.greeting h1 {
  font-size: clamp(36px, 5vw, 52px);
  line-height: 1.1;
  letter-spacing: -0.01em;
}

.greeting .lede {
  max-width: 46ch;
  text-wrap: pretty;
}

.pair-box {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 10px 10px 10px 16px;
  border: 1px solid color-mix(in srgb, var(--ink) 16%, transparent);
  border-radius: 4px;
  background: var(--sheet);
}

.pair-box .mono {
  font-size: 14px;
  font-weight: 500;
}

.pair-box .tap {
  padding: 0 8px;
  font-weight: 500;
}

/* Overview: cards */

.cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(360px, 100%), 1fr));
  gap: 24px;
}

.card {
  display: flex;
  flex-direction: column;
  gap: 20px;
  padding: 28px;
  border: 1px solid var(--line-1);
  border-radius: 4px;
  background: var(--sheet);
  box-shadow: var(--shadow-card);
}

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

.card-head h2 {
  font-size: 22px;
}

.count {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 10px;
}

.big {
  font-family: var(--serif);
  font-size: 56px;
  line-height: 1;
}

.card-foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding-top: 16px;
  border-top: 1px dashed var(--rule);
}

/* Tally marks */

.tally {
  display: flex;
  flex-wrap: wrap;
  gap: 14px 18px;
  padding: 4px 0;
}

.tally-group {
  position: relative;
  display: flex;
  gap: 6px;
  height: 34px;
  padding: 0 4px;
}

.bar {
  width: 2px;
  height: 34px;
  border-radius: 2px;
  background: color-mix(in srgb, var(--ink) 16%, transparent);
}

.bar.used {
  background: var(--ink);
  transform-origin: 50% 100%;
}

.bar.a {
  transform: rotate(-3deg);
  animation: st-draw-a 170ms ease-out both;
}

.bar.b {
  height: 32px;
  margin-top: 2px;
  transform: rotate(2deg);
  animation: st-draw-b 170ms ease-out both;
}

.strike {
  position: absolute;
  top: 16px;
  right: -2px;
  left: -2px;
  height: 2px;
  border-radius: 2px;
  background: var(--blue);
  transform: rotate(-28deg);
  animation: st-strike 220ms ease-out both;
}

/* Calendar */

.calendar {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.weekdays,
.days {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
}

.weekdays {
  font-family: var(--mono);
  font-size: 11px;
  color: var(--ink-3);
  text-align: center;
}

.days {
  row-gap: 2px;
}

.day {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  padding: 4px 0;
}

.n {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 22px;
  font-family: var(--mono);
  font-size: 12px;
  color: var(--ink-2);
}

.n.future {
  color: color-mix(in srgb, var(--ink) 30%, transparent);
}

.n.today {
  border: 1.5px solid var(--blue);
  border-radius: 50%;
  color: var(--blue);
  font-weight: 500;
  transform: rotate(-8deg);
}

.dot-slot {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 14px;
}

.dot {
  display: inline-block;
  border-radius: 50%;
  background: var(--blue);
}

.dot-slot .dot {
  animation: st-dot 280ms ease-out both;
}

.dot.l1 {
  width: 6px;
  height: 6px;
}

.dot.l2 {
  width: 10px;
  height: 10px;
}

.dot.l3 {
  width: 14px;
  height: 14px;
}

.legend {
  display: flex;
  align-items: center;
  gap: 16px;
  font-size: 12px;
  color: var(--ink-3);
}

.legend > span {
  display: flex;
  align-items: center;
  gap: 6px;
}

/* Lately */

.lately {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.lately-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  padding-bottom: 8px;
  border-bottom: 1.5px solid var(--ink);
}

.lately-head h2 {
  font-size: 26px;
}

.lately ol {
  display: flex;
  flex-direction: column;
  margin: 0;
  padding: 0;
  list-style: none;
}

.lately li {
  display: grid;
  grid-template-columns: 76px minmax(0, 1fr) auto;
  gap: 6px 20px;
  align-items: center;
  padding: 18px 0;
  border-bottom: 1px dashed var(--rule);
}

.when {
  display: flex;
  flex-direction: column;
  gap: 2px;
  font-size: 12px;
  color: var(--ink-3);
}

.words {
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 0;
}

.translation {
  font-family: var(--serif);
  font-size: 22px;
  line-height: 1.25;
  overflow-wrap: anywhere;
}

/* A long search doesn't take over the list: what was typed gets one line, the translation two,
   then an ellipsis. The text is all still there (title shows it on hover, copy and the YouTube
   link use all of it, screen readers read it). */
.words > .muted,
.words > .translation {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.words > .muted {
  -webkit-line-clamp: 1;
  line-clamp: 1;
}

.words > .translation {
  -webkit-line-clamp: 2;
  line-clamp: 2;
}

.hl {
  padding: 0 2px;
  background-image: linear-gradient(180deg, transparent 56%, var(--highlight) 56%);
  background-repeat: no-repeat;
  background-size: 100% 100%;
  box-decoration-break: clone;
  -webkit-box-decoration-break: clone;
  animation: st-sweep 520ms cubic-bezier(0.3, 0.7, 0.4, 1) both;
}

.row-end {
  display: flex;
  align-items: center;
  gap: 4px;
}

.badge {
  padding: 4px 8px;
  border: 1px solid var(--rule);
  border-radius: 3px;
  font-size: 12px;
  white-space: nowrap;
}

.icon-link {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
}

.hl.static {
  animation: none;
}

/* Shared page header */

.page-head {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.page-head .label {
  font-size: 12px;
  letter-spacing: 0.06em;
}

.page-head h1 {
  font-size: clamp(36px, 5vw, 52px);
  line-height: 1.05;
}

.page-head .lede {
  max-width: 52ch;
  text-wrap: pretty;
}

/* History */

.history {
  gap: 36px;
}

.filters {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 16px 24px;
}

/* The language chips are one row that scrolls sideways (snapping to a chip) rather than stacking
   into more rows; the scrollbar is hidden, the partly visible chip at the edge says there's more.
   The vertical padding leaves room for focus rings, which the scroller would clip. */
.chips {
  display: flex;
  /* Basis 0: the chips take the room beside the word search and scroll in it, rather than pushing
     the search onto a line of its own. */
  flex: 1 1 0;
  gap: 8px;
  min-width: 0;
  padding-block: 4px;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x proximity;
  scrollbar-width: none;
}

.chips::-webkit-scrollbar {
  display: none;
}

.chip {
  display: flex;
  flex: none;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  padding: 0 16px;
  border: 1.5px solid color-mix(in srgb, var(--ink) 25%, transparent);
  border-radius: 999px;
  background: var(--sheet);
  color: var(--ink);
  font: 500 14px var(--sans);
  cursor: pointer;
  scroll-snap-align: start;
}

/* With a mouse, arrows at the row's ends (CSS carousel scroll buttons, Chrome 135+; elsewhere the row
   just scrolls). The browser makes them real buttons, and disables each one when there's nothing
   more to scroll its way: a disabled one isn't shown, so chips that fit get no arrows. Touch swipes. */
@media (hover: hover) and (pointer: fine) {
  .chips {
    anchor-name: --chips;
  }

  .chips::scroll-button(*) {
    position: absolute;
    position-anchor: --chips;
    top: anchor(center);
    translate: 0 -50%;
    width: 32px;
    height: 32px;
    border: 1px solid color-mix(in srgb, var(--ink) 12%, transparent);
    border-radius: 50%;
    background: var(--sheet);
    box-shadow: var(--shadow-pop);
    color: var(--ink);
    font: 600 17px / 1 var(--sans);
    cursor: pointer;
    transition:
      opacity 150ms var(--ease-out),
      scale 160ms var(--ease-out);
  }

  /* biome-ignore lint/correctness/noUnknownTypeSelector: ::scroll-button(left) is the CSS carousel pseudo-element, which Biome doesn't parse yet */
  .chips::scroll-button(left) {
    content: "‹" / "Scroll languages left";
    left: anchor(left);
  }

  /* biome-ignore lint/correctness/noUnknownTypeSelector: ::scroll-button(right) is the CSS carousel pseudo-element, which Biome doesn't parse yet */
  .chips::scroll-button(right) {
    content: "›" / "Scroll languages right";
    right: anchor(right);
  }

  .chips::scroll-button(*):active {
    scale: 0.97;
  }

  .chips::scroll-button(*):disabled {
    opacity: 0;
    pointer-events: none;
  }
}

.chip[aria-pressed="true"] {
  border-color: var(--ink);
  background: var(--ink);
  color: var(--paper);
}

.chip-count {
  font-family: var(--mono);
  font-size: 12px;
  color: var(--ink-3);
}

.chip[aria-pressed="true"] .chip-count {
  color: inherit;
  opacity: 0.8;
}

.find {
  display: flex;
  flex: 0 1 300px;
  flex-direction: column;
  gap: 6px;
  min-width: 200px;
}

.find label {
  font-size: 13px;
  color: var(--ink-2);
}

.find input {
  width: 100%;
  min-height: 44px;
  padding: 0 14px;
  border: 1.5px solid color-mix(in srgb, var(--ink) 25%, transparent);
  border-radius: 4px;
  background: var(--sheet);
  color: var(--ink);
  font: 400 15px var(--sans);
}

.find input::placeholder {
  color: var(--ink-3);
}

.days-list {
  display: flex;
  flex-direction: column;
  gap: 36px;
  transition: opacity 150ms ease;
}

/* A new batch for changed filters is on its way, or didn't come: what's shown is for the old
   filters. */
.days-list[aria-busy="true"],
.days-list[data-stale] {
  opacity: 0.55;
}

.history-stale {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px 16px;
  padding: 12px 16px;
  border: 1.5px solid color-mix(in srgb, var(--red) 45%, transparent);
  border-radius: 6px;
  background: var(--sheet);
  font-size: 14px;
  color: var(--ink);
}

.day-group {
  display: flex;
  flex-direction: column;
}

.day-group h2 {
  display: flex;
  align-items: baseline;
  gap: 12px;
  padding-bottom: 8px;
  border-bottom: 1.5px solid var(--ink);
}

.day-label {
  font-size: 22px;
}

.day-date {
  font-family: var(--mono);
  font-size: 12px;
  color: var(--ink-3);
}

.rows {
  display: flex;
  flex-direction: column;
  margin: 0;
  padding: 0;
  list-style: none;
}

/* A row folds away when it's deleted: the li's one grid track goes from 1fr to 0fr after the row
   has faded, so the rows below glide up instead of jumping. .row-clip lets the track shrink
   below the row's padding. */
.rows li {
  display: grid;
  grid-template-rows: 1fr;
  border-bottom: 1px dashed var(--rule);
  transition:
    opacity 150ms var(--ease-out),
    grid-template-rows 200ms var(--ease-out) 100ms,
    border-color 200ms var(--ease-out) 100ms;
}

.rows .row-clip {
  min-height: 0;
}

.rows .row {
  display: grid;
  grid-template-columns: 56px minmax(0, 1fr) auto;
  gap: 6px 20px;
  align-items: center;
  padding: 16px 0;
  transform-origin: left center;
  transition: transform 150ms var(--ease-out);
}

.rows li[data-state="deleting"] {
  opacity: 0.55;
}

.rows li[data-state="leaving"] {
  grid-template-rows: 0fr;
  border-color: transparent;
  opacity: 0;
}

.rows li[data-state="leaving"] .row-clip {
  overflow: hidden;
}

.rows li[data-state="leaving"] .row {
  transform: scale(0.98);
}

.time {
  font-size: 13px;
}

.rows .translation {
  font-size: 21px;
}

.rows .badge {
  margin-right: 6px;
}

.rows .row-end {
  gap: 2px;
}

.icon-button {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border: 0;
  border-radius: 4px;
  background: transparent;
  color: var(--ink-2);
  cursor: pointer;
}

.icon-button[aria-disabled="true"] {
  opacity: 0.4;
  cursor: default;
}

/* The trash button the delete popover is open from: its anchor, and red while it's open */
.icon-button.delete[data-target] {
  anchor-name: --hist-trash;
}

.history:has(#hist-pop:popover-open) .icon-button.delete[data-target] {
  background: color-mix(in srgb, var(--red) 10%, transparent);
  color: var(--red);
}

@media (hover: hover) and (pointer: fine) {
  .icon-button.delete:hover:not([aria-disabled="true"]) {
    color: var(--red);
  }
}

/* Deleting a history entry: "Delete this search?" is a native popover (top layer, Escape and clicks
   outside close it). It pops out of the trash button it was opened from: anchored above it, right
   edges lined up, scaling from the button's centre (22px in from the right edge).

   In: 160ms, the strong ease-out, from 95% and transparent (@starting-style).
   Out: 150ms plain ease-out back to that, slower to start than the strong curve, which at this
   length is gone in two frames. display and overlay go along (allow-discrete), so the popover stays
   rendered, and in the top layer, until it has faded. */
.delete-pop {
  width: max-content;
  max-width: min(260px, calc(100vw - 32px));
  padding: 12px;
  border: 1px solid color-mix(in srgb, var(--ink) 8%, transparent);
  border-radius: 8px;
  background: var(--sheet);
  box-shadow: var(--shadow-pop);
  color: var(--ink);
  opacity: 0;
  transform: scale(0.95);
  transform-origin: calc(100% - 22px) 100%;
  transition:
    opacity 150ms ease-out,
    transform 150ms ease-out,
    overlay 150ms ease-out allow-discrete,
    display 150ms ease-out allow-discrete;
}

.delete-pop:popover-open {
  opacity: 1;
  transform: none;
  transition:
    opacity 160ms var(--ease-out),
    transform 160ms var(--ease-out),
    overlay 160ms var(--ease-out) allow-discrete,
    display 160ms var(--ease-out) allow-discrete;
}

@starting-style {
  .delete-pop:popover-open {
    opacity: 0;
    transform: scale(0.95);
  }
}

/* Without anchor positioning the popover stays where browsers put one: the middle of the screen. */
@supports (anchor-name: --a) {
  .delete-pop {
    inset: auto;
    margin: 0 0 6px;
    position-anchor: --hist-trash;
    position-area: block-start span-inline-start;
    /* No room above (the row is at the top of the screen): open below. */
    position-try-fallbacks: flip-block;
  }
}

.delete-pop-title {
  margin: 0;
  font: 600 14px var(--sans);
  color: var(--ink);
}

.delete-pop-note {
  margin: 2px 0 0;
  font-size: 13px;
  color: var(--ink-2);
}

.delete-pop-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 12px;
}

.pop-keep,
.pop-delete {
  min-height: 36px;
  padding: 0 14px;
  border-radius: 6px;
  font: 600 14px var(--sans);
  cursor: pointer;
  transition: transform 160ms var(--ease-out);
}

.pop-keep:active,
.pop-delete:active {
  transform: scale(0.97);
}

.pop-keep {
  border: 1.5px solid color-mix(in srgb, var(--ink) 25%, transparent);
  background: var(--sheet);
  color: var(--ink);
}

.pop-delete {
  border: 1.5px solid var(--red);
  background: var(--red);
  color: var(--paper);
}

.delete-failed {
  font-size: 12px;
  font-weight: 600;
  color: var(--red);
}

.copied {
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  height: 44px;
  font-size: 12px;
  font-weight: 600;
  color: var(--blue);
}

.empty {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 40px 0;
  border-top: 1px dashed var(--rule);
  border-bottom: 1px dashed var(--rule);
}

.empty-title {
  font-family: var(--serif);
  font-size: 22px;
}

/* Under the list: "Show 20 older" while there are more, and how many of how many are shown. */
.history-more {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
}

.history-count {
  margin: 0;
  font-family: var(--mono);
  font-size: 12px;
  color: var(--ink-3);
}

.history-foot {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 8px;
  font-size: 14px;
  color: var(--ink-2);
}

/* Stats */

.stats {
  gap: 48px;
}

.stats .page-head {
  gap: 18px;
}

.stats-headline {
  max-width: 26ch;
  font-size: clamp(28px, 3.6vw, 40px);
  line-height: 1.3;
  text-wrap: pretty;
}

.stats-headline .hl {
  padding: 0 3px;
}

.card-head.wrap {
  flex-wrap: wrap;
  gap: 8px 16px;
}

.chart {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.bars {
  position: relative;
  display: grid;
  align-items: end;
  gap: 12px;
  border-bottom: 1.5px solid var(--ink);
}

.axis {
  display: grid;
  gap: 12px;
  font-size: 12px;
  color: var(--ink-2);
  text-align: center;
}

.col {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  gap: 6px;
  height: 100%;
}

.col-value {
  font-size: 12px;
}

.col-value.small {
  font-size: 11px;
  color: var(--ink-2);
}

.col-bar {
  display: block;
  width: 100%;
  max-width: 44px;
  border-radius: 2px 2px 0 0;
  background: var(--blue);
}

.col-bar.running {
  border: 1.5px solid var(--blue);
  border-bottom: 0;
  background: repeating-linear-gradient(
    -45deg,
    color-mix(in srgb, var(--blue) 55%, transparent) 0 2px,
    transparent 2px 7px
  );
}

.col-bar.narrow {
  max-width: 28px;
}

.col-bar.soft {
  background: color-mix(in srgb, var(--blue) 35%, transparent);
}

.limit-line {
  position: absolute;
  right: 0;
  left: 0;
  border-top: 1.5px dashed var(--margin-red);
}

/* Left end: the first months are usually the short ones, so the label stays clear of the values. */
.limit-label {
  position: absolute;
  left: 0;
  padding: 0 4px;
  background: var(--sheet);
  font-size: 11px;
  color: var(--red);
}

.week-bars {
  height: 130px;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 10px;
}

.week-axis {
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 10px;
}

.langs {
  display: flex;
  flex-direction: column;
  gap: 20px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.lang {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.lang-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
}

.lang-head .mono {
  font-size: 13px;
}

.lang-names {
  display: flex;
  align-items: baseline;
  gap: 10px;
  font-size: 16px;
}

.native {
  font-family: var(--serif);
  font-size: 15px;
  color: var(--ink-2);
}

.lang-track {
  position: relative;
  display: block;
  height: 12px;
  border-bottom: 1px solid color-mix(in srgb, var(--ink) 22%, transparent);
  background-image: repeating-linear-gradient(
    90deg,
    color-mix(in srgb, var(--ink) 22%, transparent) 0 1px,
    transparent 1px 10%
  );
}

.lang-fill {
  position: absolute;
  top: 2px;
  bottom: 2px;
  left: 0;
  border-radius: 1px;
  background: var(--blue);
}

/* Premium-only sections: blurred under an unlock call to action on Free */

.locked-host {
  position: relative;
  overflow: hidden;
}

.lockable {
  display: flex;
  flex-direction: column;
  gap: 18px;
}

.is-locked {
  position: relative;
}

.blurred {
  display: flex;
  flex-direction: column;
  gap: 18px;
  filter: blur(6px);
  user-select: none;
}

.unlock {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
  padding: 0 16px;
  text-align: center;
}

.unlock-title {
  font-family: var(--serif);
  font-size: 22px;
}

.button-dark {
  display: flex;
  align-items: center;
  min-height: 44px;
  padding: 0 18px;
  border-radius: 4px;
  background: var(--ink);
  color: var(--paper);
  font-size: 14px;
  font-weight: 600;
  text-decoration: none;
}

.button-dark:hover {
  /* Not the highlighter: in dark mode it's translucent and this button is light. */
  background: var(--accent-fill);
  color: var(--on-accent);
}

.words-section {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.word-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(200px, 100%), 1fr));
  gap: 20px;
  margin: 0;
  padding: 8px 0 0;
  list-style: none;
}

.word-card {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 18px 20px 16px;
  border: 1px solid color-mix(in srgb, var(--ink) 16%, transparent);
  border-top: 3px solid var(--margin-red);
  border-radius: 2px;
  background: var(--sheet);
  box-shadow: 0 2px 0 color-mix(in srgb, var(--ink) 5%, transparent);
}

/* Index cards, pinned slightly askew */
.word-card:nth-child(6n + 1) {
  transform: rotate(-0.8deg);
}

.word-card:nth-child(6n + 2) {
  transform: rotate(0.6deg);
}

.word-card:nth-child(6n + 3) {
  transform: rotate(-0.4deg);
}

.word-card:nth-child(6n + 4) {
  transform: rotate(0.9deg);
}

.word-card:nth-child(6n + 5) {
  transform: rotate(-0.6deg);
}

.word-card:nth-child(6n) {
  transform: rotate(0.4deg);
}

.word-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
}

.word {
  font-family: var(--serif);
  font-size: 28px;
  line-height: 1.15;
}

.word-card .label {
  letter-spacing: 0.06em;
}

/* Plan */

.plan {
  gap: 40px;
}

.plan-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 20px 32px;
}

.plan-head .lede {
  max-width: 50ch;
}

.toggle {
  display: flex;
  gap: 4px;
  padding: 4px;
  border: 1.5px solid color-mix(in srgb, var(--ink) 20%, transparent);
  border-radius: 999px;
  background: var(--sheet);
}

/* 40px pill inside a 4px padded track: the whole control is 48px tall */
.toggle button {
  min-height: 40px;
  padding: 0 18px;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--ink);
  font: 500 14px var(--sans);
  cursor: pointer;
}

.toggle button[aria-pressed="true"] {
  background: var(--ink);
  color: var(--paper);
  font-weight: 600;
}

.plan-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(340px, 100%), 1fr));
  align-items: stretch;
  gap: 28px;
}

.plan-card-big {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 24px;
  padding: 32px;
  border: 1px solid color-mix(in srgb, var(--ink) 16%, transparent);
  border-radius: 4px;
  background: var(--sheet);
  box-shadow: var(--shadow-card);
}

.plan-card-big.premium {
  border: 2px solid var(--blue);
  box-shadow: 6px 6px 0 color-mix(in srgb, var(--blue) 12%, transparent);
}

.plan-title {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.plan-title h2 {
  font-size: 30px;
}

.premium-title {
  color: var(--blue);
}

.price {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 8px;
}

.price .lede {
  font-size: 15px;
}

.amount {
  font-family: var(--serif);
  font-size: 40px;
  line-height: 1;
}

.stamp {
  position: absolute;
  top: 22px;
  right: 22px;
  padding: 4px 10px;
  border: 2px solid var(--stamp-red);
  border-radius: 4px;
  color: var(--stamp-red);
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.1em;
  transform: rotate(-7deg);
}

.features {
  display: flex;
  flex-direction: column;
  margin: 0;
  padding: 0;
  border-top: 1px dashed var(--rule);
  list-style: none;
}

.features li {
  display: flex;
  align-items: baseline;
  gap: 12px;
  padding: 12px 0;
  border-bottom: 1px dashed var(--rule);
  font-size: 15px;
}

.features strong {
  font-weight: 600;
}

.check {
  color: var(--blue);
}

.plan-foot {
  margin-top: auto;
}

/* Checkout or the portal didn't open, or a payment failed: said in red, under the button. */
.plan-foot.plan-error {
  color: var(--red);
}

/* Stripe test mode only (a test key, outside production): two resets, under the note. */
.test-panel {
  align-self: flex-start;
  max-width: 560px;
  margin: 32px 0 0 8px;
  padding: 16px 20px;
  border: 1px dashed var(--line-3);
  border-radius: var(--radius-card);
}

.test-resets {
  display: flex;
  flex-wrap: wrap;
  gap: 12px 20px;
  margin-top: 10px;
}

/* A button and its "i"; the explanation shows only on hovering or focusing the "i". */
.test-panel .tip {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

.test-panel .tip-icon {
  display: inline-grid;
  place-items: center;
  width: 20px;
  height: 20px;
  padding: 0;
  border: 1px solid var(--line-3);
  border-radius: 50%;
  background: transparent;
  color: var(--ink-3);
  font: italic 600 12px / 1 var(--serif);
  cursor: help;
}

.test-panel .tip-text {
  position: absolute;
  bottom: calc(100% + 8px);
  left: 0;
  z-index: 10;
  width: max-content;
  max-width: min(300px, 80vw);
  padding: 8px 12px;
  border-radius: var(--radius-popover);
  background: var(--ink);
  box-shadow: var(--shadow-pop);
  color: var(--paper);
  font-size: 13px;
  line-height: 1.45;
  opacity: 0;
  pointer-events: none;
  transform: translateY(4px);
  transition:
    opacity 150ms ease-out,
    transform 150ms ease-out,
    visibility 150ms;
  visibility: hidden;
}

.test-panel .tip-icon:hover ~ .tip-text,
.test-panel .tip-icon:focus-visible ~ .tip-text {
  opacity: 1;
  transform: none;
  visibility: visible;
}

@media (prefers-reduced-motion: reduce) {
  .test-panel .tip-text {
    transition: none;
  }
}

.test-panel .button-outline:disabled {
  border-color: color-mix(in srgb, var(--ink) 25%, transparent);
  color: var(--ink-3);
  cursor: default;
}

.center {
  text-align: center;
}

.button-accent {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 52px;
  margin-top: auto;
  padding: 0 24px;
  border: 0;
  border-radius: 4px;
  background: var(--accent-fill);
  color: var(--on-accent);
  font: 600 16px var(--sans);
  cursor: pointer;
}

.button-accent + .plan-foot {
  margin-top: 0;
}

.note {
  position: relative;
  align-self: flex-start;
  max-width: 560px;
  margin: 12px 0 0 8px;
  padding: 32px 32px 26px;
  border: 1px solid var(--line-1);
  border-radius: 2px;
  background: var(--sheet);
  box-shadow: 0 3px 0 color-mix(in srgb, var(--ink) 5%, transparent);
  transform: rotate(-0.6deg);
}

.tape {
  position: absolute;
  top: -12px;
  left: 40px;
  width: 96px;
  height: 24px;
  border-right: 1px dashed color-mix(in srgb, var(--ink) 12%, transparent);
  border-left: 1px dashed color-mix(in srgb, var(--ink) 12%, transparent);
  background: var(--highlight);
  transform: rotate(-4deg);
}

.note-text {
  margin-bottom: 14px;
  font-family: var(--serif);
  font-size: 19px;
  line-height: 1.55;
  text-wrap: pretty;
}

.signature {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  color: var(--blue);
  font-family: var(--serif);
  font-size: 22px;
}

/* Account */

.account {
  gap: 40px;
}

.account-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 20px 28px;
}

.big-avatar {
  width: 88px;
  height: 88px;
  font-size: 40px;
  box-shadow:
    0 0 0 6px var(--paper),
    0 0 0 7px color-mix(in srgb, var(--ink) 25%, transparent);
}

.account-title {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.account-title h1 {
  font-size: clamp(32px, 4.4vw, 46px);
  line-height: 1.05;
}

.account-title .lede {
  font-size: 15px;
}

.settings-row {
  display: flex;
  flex-wrap: wrap;
  gap: 16px 40px;
  padding: 28px 0;
  border-top: 1px dashed color-mix(in srgb, var(--ink) 25%, transparent);
}

.settings-row.first {
  border-top: 1.5px solid var(--ink);
}

.settings-row:last-of-type {
  border-bottom: 1px dashed color-mix(in srgb, var(--ink) 25%, transparent);
}

.settings-intro {
  display: flex;
  flex: 1 1 200px;
  flex-direction: column;
  gap: 6px;
}

.settings-title {
  font-size: 22px;
}

.settings-intro .muted {
  line-height: 1.5;
  color: var(--ink-2);
}

.settings-body {
  flex: 999 1 380px;
  min-width: 0;
}

.stack {
  display: flex;
  flex-direction: column;
  gap: 18px;
}

.stack.tight {
  gap: 4px;
}

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

.field {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.field label,
.field-label {
  font-size: 13px;
  font-weight: 500;
  color: var(--ink-2);
}

.field input,
.field select,
.add-pick select {
  width: 100%;
  min-height: 44px;
  padding: 0 14px;
  border: 1.5px solid color-mix(in srgb, var(--ink) 25%, transparent);
  border-radius: 4px;
  background: var(--sheet);
  color: var(--ink);
  font: 400 15px var(--sans);
}

.field select,
.add-pick select {
  padding: 0 12px;
}

.field input[readonly] {
  background: var(--paper);
  color: var(--ink-2);
}

.field select.accent-select {
  border-color: var(--blue);
}

button.button-dark {
  border: 1.5px solid var(--ink);
  font-family: var(--sans);
  cursor: pointer;
}

button.button-dark:disabled {
  border-color: color-mix(in srgb, var(--ink) 25%, transparent);
  background: transparent;
  color: var(--ink-3);
  cursor: default;
}

.lang-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.lang-chip {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  padding: 0 4px 0 14px;
  border: 1.5px solid color-mix(in srgb, var(--ink) 25%, transparent);
  border-radius: 999px;
  background: var(--sheet);
  font-size: 14px;
}

.lang-chip .native {
  font-size: 14px;
}

.chip-x {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--ink-2);
  cursor: pointer;
}

.chip-x:hover {
  background: color-mix(in srgb, var(--ink) 6%, transparent);
}

.add-chip {
  display: flex;
  align-items: center;
  gap: 6px;
  min-height: 44px;
  padding: 0 14px;
  border: 1.5px dashed color-mix(in srgb, var(--blue) 60%, transparent);
  border-radius: 999px;
  background: transparent;
  color: var(--blue);
  font: 500 14px var(--sans);
  cursor: pointer;
}

.add-pick select {
  min-width: 200px;
  border-radius: 999px;
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.connected {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin-bottom: 10px;
  font-size: 15px;
}

.connected strong {
  font-weight: 600;
}

.live-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--blue);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--blue) 15%, transparent);
}

.pref {
  display: flex;
  align-items: flex-start;
  gap: 14px;
  padding: 12px 0;
  border-top: 1px dashed color-mix(in srgb, var(--ink) 18%, transparent);
}

.pref input {
  flex: none;
  width: 20px;
  height: 20px;
  margin: 2px 0 0;
  accent-color: var(--blue);
  cursor: pointer;
}

.pref label {
  display: flex;
  flex-direction: column;
  gap: 3px;
  cursor: pointer;
}

.pref-title {
  font-size: 15px;
  font-weight: 500;
}

.pref .muted {
  color: var(--ink-2);
}

.data-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px 16px;
}

.spacer {
  flex: 1 1 auto;
}

.button-outline {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  padding: 0 18px;
  border: 1.5px solid var(--ink);
  border-radius: 4px;
  background: var(--sheet);
  color: var(--ink);
  font: 600 14px var(--sans);
  text-decoration: none;
  cursor: pointer;
}

.danger-link {
  min-height: 44px;
  padding: 0 12px;
  border: 0;
  background: transparent;
  color: var(--red);
  font: 600 14px var(--sans);
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
}

.quiet-button {
  min-height: 44px;
  padding: 0 4px;
  border: 0;
  background: transparent;
  color: var(--ink-2);
  font: 500 14px var(--sans);
  cursor: pointer;
}

/* Moments: day one */

.day-one {
  gap: 48px;
}

.ruled-title {
  padding-bottom: 8px;
  border-bottom: 1.5px solid var(--ink);
  font-size: 26px;
}

.how {
  display: flex;
  flex-direction: column;
  gap: 24px;
}

.steps {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(240px, 100%), 1fr));
  gap: 28px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.step {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.step .lede {
  font-size: 15px;
}

/* Circled by hand, each at its own angle */
.step-n {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 46px;
  height: 42px;
  border: 1.5px solid var(--blue);
  border-radius: 50%;
  color: var(--blue);
  font-family: var(--serif);
  font-size: 22px;
  transform: rotate(-8deg);
}

.step:nth-child(2) .step-n {
  transform: rotate(5deg);
}

.step:nth-child(3) .step-n {
  transform: rotate(-3deg);
}

.step-title {
  font-size: 17px;
  font-weight: 600;
}

.card-title {
  font-size: 22px;
}

.sample {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.sample .muted {
  font-size: 15px;
}

.sample-to {
  font-family: var(--serif);
  font-size: 28px;
  line-height: 1.25;
}

.hl.slow {
  animation-duration: 640ms;
  animation-delay: 500ms;
}

.small-button {
  align-self: flex-start;
  min-height: 44px;
  padding: 0 18px;
  font-size: 15px;
  text-decoration: none;
}

.empty-lines {
  display: flex;
  flex-direction: column;
}

.line {
  height: 56px;
  border-bottom: 1px dashed var(--rule);
}

.line.first {
  display: flex;
  align-items: flex-end;
  padding-bottom: 10px;
}

.line-hint {
  font-family: var(--serif);
  font-size: 18px;
  color: var(--ink-3);
}

/* Moments: limit reached */

.limit {
  gap: 40px;
}

.full-page {
  gap: 24px;
  padding: clamp(24px, 4vw, 44px);
}

.tally.full {
  gap: 14px 22px;
  padding: 6px 0;
}

.tally.full .tally-group {
  gap: 7px;
  height: 42px;
}

.tally.full .bar {
  height: 42px;
}

.bar.t1 {
  transform: rotate(-3deg);
}

.bar.t2 {
  height: 40px;
  margin-top: 2px;
  transform: rotate(2deg);
}

.bar.t3 {
  transform: rotate(-2deg);
}

.bar.t4 {
  height: 41px;
  margin-top: 1px;
  transform: rotate(3deg);
}

.tally.full .strike {
  top: 20px;
}

.strike.still {
  animation: none;
}

.strike.last {
  animation-duration: 240ms;
}

.full-text {
  display: flex;
  flex-direction: column;
  gap: 10px;
  max-width: 56ch;
}

.full-text h2 {
  font-size: clamp(26px, 3.2vw, 34px);
  line-height: 1.2;
}

.full-text .lede {
  line-height: 1.55;
  text-wrap: pretty;
}

.full-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px 20px;
}

.full-actions .button-accent {
  min-height: 48px;
  margin-top: 0;
  padding: 0 22px;
  font-size: 15px;
  text-decoration: none;
}

.full-actions .quiet-button {
  min-height: 48px;
  padding: 0 6px;
  color: var(--blue);
  font-size: 15px;
}

.premium-card {
  border: 1.5px solid var(--blue);
}

/* Moments: just upgraded */

.upgraded {
  gap: 44px;
}

.page-head h1.huge {
  font-size: clamp(40px, 6vw, 64px);
}

.upgraded .page-head .lede {
  max-width: 48ch;
  font-size: 17px;
}

.receipt {
  position: relative;
  align-self: flex-start;
  width: 100%;
  max-width: 560px;
  padding: 32px 32px 28px;
  border: 1px solid var(--line-1);
  border-radius: 2px;
  background: var(--sheet);
  box-shadow: 0 3px 0 color-mix(in srgb, var(--ink) 5%, transparent);
}

.receipt h2 {
  margin-bottom: 20px;
  padding-right: 96px;
  font-size: 22px;
}

/* Pressed into the corner, clear of the first row's value */
.paid {
  position: absolute;
  top: 12px;
  right: 22px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  padding: 8px 14px;
  border: 3px double var(--stamp-red);
  border-radius: 6px;
  color: var(--stamp-red);
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.14em;
  transform: rotate(-10deg);
  animation: st-stamp 420ms cubic-bezier(0.2, 0.8, 0.3, 1.1) 350ms both;
}

.paid-word {
  font-size: 22px;
}

.receipt dl {
  display: flex;
  flex-direction: column;
  margin: 0;
  border-top: 1px dashed color-mix(in srgb, var(--ink) 25%, transparent);
}

.receipt-row {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  padding: 12px 0;
  border-bottom: 1px dashed color-mix(in srgb, var(--ink) 25%, transparent);
  font-size: 14px;
}

.receipt-row dt {
  color: var(--ink-2);
}

.receipt-row dd {
  margin: 0;
  overflow-wrap: anywhere;
  text-align: right;
}

.opened {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

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

.opened-cards li {
  display: flex;
  animation: st-rise 360ms ease-out 800ms both;
}

.opened-cards li:nth-child(2) {
  animation-delay: 900ms;
}

.opened-cards li:nth-child(3) {
  animation-delay: 1000ms;
}

.opened-card {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: 8px;
  padding: 22px;
  border: 1px solid var(--line-1);
  border-radius: 4px;
  background: var(--sheet);
  color: var(--ink);
  text-decoration: none;
}

.opened-card .strong {
  font-size: 16px;
}

.opened-card .muted {
  line-height: 1.5;
  color: var(--ink-2);
}

.opened-mark {
  font-family: var(--serif);
  font-size: 22px;
  line-height: 24px;
  color: var(--blue);
}

.opened-icon {
  color: var(--blue);
}

@keyframes st-stamp {
  0% {
    opacity: 0;
    transform: rotate(-10deg) scale(1.8);
  }
  60% {
    opacity: 1;
    transform: rotate(-10deg) scale(0.94);
  }
  100% {
    opacity: 1;
    transform: rotate(-10deg) scale(1);
  }
}

@keyframes st-rise {
  from {
    opacity: 0;
    transform: translateY(8px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* Gate: before the dashboard (loading, signed out, problems) */

.gate {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 100vh;
  padding: 24px 16px;
}

.gate-card {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 16px;
  width: 100%;
  max-width: 480px;
  padding: 40px clamp(24px, 6vw, 44px) 36px;
  border: 1px solid var(--line-1);
  border-left: 2px solid var(--margin-red);
  border-radius: 2px;
  background: var(--sheet);
  box-shadow: 0 3px 0 color-mix(in srgb, var(--ink) 5%, transparent);
}

.gate-card h1 {
  font-size: clamp(28px, 5vw, 36px);
  line-height: 1.15;
}

.big-mark {
  width: 48px;
  height: 48px;
  font-size: 14px;
}

.gate-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 16px;
  margin-top: 8px;
}

.gate-actions .button-accent {
  min-height: 48px;
  margin-top: 0;
}

.gate-actions .quiet-button {
  color: var(--blue);
  font-size: 15px;
}

.gate-actions a {
  text-decoration: none;
}

.gate-actions .quiet-button {
  display: inline-flex;
  align-items: center;
}

.gate .mono {
  overflow-wrap: anywhere;
}

/* /sign-in and /sign-up: Clerk's own card (clerk-bridge.js), with the legal links under it */
.gate-clerk {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
  max-width: 100%;
}

clerk-auth {
  display: block;
  max-width: 100%;
}

/* Too narrow for a sidebar beside the page: stack it on top, full width, scrolling away. */
/* Narrow screens: the sidebar becomes a slim header. One row on tablets (logo, sections as tabs,
   the plan as a pill); on phones the tabs get a row of their own. The user chip goes (Account is a
   tab), and the legal links move to the foot of the page (.main-foot). */
@media (max-width: 820px) {
  .app {
    flex-direction: column;
  }

  .sidebar {
    position: static;
    flex: none;
    flex-flow: row wrap;
    align-items: center;
    align-self: stretch;
    gap: 4px 16px;
    height: auto;
    overflow-y: visible;
    padding: 12px clamp(20px, 4vw, 64px);
    border-right: 0;
    border-bottom: 1px solid var(--margin-red);
  }

  .logo-mark {
    width: 30px;
    height: 30px;
  }

  .logo-name {
    font-size: 17px;
  }

  .sidebar nav {
    flex: 1;
    min-width: 0;
  }

  .sidebar ul {
    flex-direction: row;
    gap: 0;
    overflow-x: auto;
    scrollbar-width: none;
  }

  .sidebar ul::-webkit-scrollbar {
    display: none;
  }

  .sidebar li a {
    padding: 0 8px;
    font-size: 14px;
    white-space: nowrap;
  }

  .sidebar .num {
    display: none;
  }

  .sidebar-foot {
    flex-direction: row;
    align-items: center;
    margin-top: 0;
  }

  .sidebar-foot .user-chip,
  .sidebar-foot .legal {
    display: none;
  }

  .plan-card {
    flex-direction: row;
    padding: 5px 10px;
    border-style: solid;
    border-radius: 999px;
    font-size: 12px;
  }

  .plan-card > :not(.plan-short) {
    display: none;
  }

  .plan-short {
    display: inline;
    font-family: var(--mono);
    font-weight: 600;
    color: var(--blue);
  }

  .main {
    padding-top: 28px;
  }

  .main-foot {
    display: block;
    margin-top: 56px;
  }

  /* The chip row runs to the screen's edges, so chips scroll out under the page gutter instead of
     being cut off inside it. */
  .chips {
    flex-basis: 100%;
    margin-inline: calc(-1 * clamp(20px, 4vw, 64px));
    padding-inline: clamp(20px, 4vw, 64px);
    scroll-padding-inline: clamp(20px, 4vw, 64px);
  }
}

/* Phones: logo and plan on the first row, the five tabs across the second. */
@media (max-width: 640px) {
  .sidebar nav {
    flex-basis: 100%;
    order: 3;
    margin: 0 -8px;
  }

  .sidebar-foot {
    order: 2;
    margin-left: auto;
  }
}

@media (max-width: 520px) {
  .lately li {
    grid-template-columns: minmax(0, 1fr) auto;
  }

  /* Three controls don't fit beside the words: they get their own line. */
  .rows .row {
    grid-template-columns: minmax(0, 1fr);
  }

  .when,
  .time {
    flex-direction: row;
    gap: 8px;
    grid-column: 1 / -1;
  }
}

/* Motion: marks are drawn in, once */

@keyframes st-draw-a {
  from {
    transform: rotate(-3deg) scaleY(0);
  }
  to {
    transform: rotate(-3deg) scaleY(1);
  }
}

@keyframes st-draw-b {
  from {
    transform: rotate(2deg) scaleY(0);
  }
  to {
    transform: rotate(2deg) scaleY(1);
  }
}

@keyframes st-strike {
  from {
    clip-path: inset(0 100% 0 0);
  }
  to {
    clip-path: inset(0 0 0 0);
  }
}

@keyframes st-sweep {
  from {
    background-size: 0% 100%;
  }
  to {
    background-size: 100% 100%;
  }
}

@keyframes st-dot {
  0% {
    transform: scale(0);
  }
  70% {
    transform: scale(1.25);
  }
  100% {
    transform: scale(1);
  }
}

@media (prefers-reduced-motion: reduce) {
  * {
    /* biome-ignore lint/complexity/noImportantStyles: reduced motion has to beat every animation rule */
    animation: none !important;
  }

  /* Fades stay, movement goes: the popover doesn't scale, and a deleted row fades out and then
     closes up at once (in 1ms, so its transitionend still comes). */
  .delete-pop,
  .delete-pop:popover-open {
    transform: none;
  }

  .rows li {
    transition:
      opacity 150ms ease,
      grid-template-rows 1ms 150ms,
      border-color 1ms 150ms;
  }

  .rows .row {
    transition: none;
  }

  .rows li[data-state="leaving"] .row {
    transform: none;
  }
}
