/* Iosevka, self-hosted. SIL OFL license in design/fonts/LICENSE.
   Source: @fontsource/iosevka (https://github.com/fontsource/font-files). */
@font-face {
  font-family: "Iosevka";
  font-style: normal;
  font-weight: 400;
  font-display: block;
  src: url("/static/fonts/iosevka-400.woff2") format("woff2");
}
@font-face {
  font-family: "Iosevka";
  font-style: normal;
  font-weight: 700;
  font-display: block;
  src: url("/static/fonts/iosevka-700.woff2") format("woff2");
}

/* ============================================================
   TOKENS — CSS custom properties
   Orbit design system — modern monochrome, dark by default,
   single sodium-orange accent. Warm greys throughout so the
   accent reads as "amber warning light" rather than brand color.
   ============================================================ */
:root {
  /* color — dark is the default */
  --color-bg: #0e0c09;       /* warm near-black */
  --color-text: #efe7d5;     /* warm cream */
  --color-muted: #7f7869;    /* warm mid-grey */
  --color-border: #1c1a17;   /* just barely visible */
  --color-accent: #ff9a3c;   /* sodium orange */

  /* type — Iosevka carries everything: headings, body, labels. One instrument, one font. */
  --font-sans: "Iosevka", ui-monospace, "Cascadia Code", "Source Code Pro", monospace;
  --font-mono: "Iosevka", ui-monospace, "Cascadia Code", "Source Code Pro", monospace;

  /* space */
  --space-xs: 0.25rem;
  --space-sm: 0.5rem;
  --space-md: 1rem;
  --space-lg: 1.5rem;
  --space-xl: 2rem;

  /* radius */
  --radius-sm: 0.25rem;
  --radius-md: 0.5rem;

  /* status dots — orbit's visual language.
     Flow items (projects, ideas, issues, designs, PRs) decay with
     time: active (sodium) if they moved in the last 7 days, stale
     (warm grey) otherwise. History entries are always done (sage) —
     the chronicle is terminal by definition and doesn't decay. */
  --color-dot-stale:  #6d6758;
  --color-dot-active: #ff9a3c;
  --color-dot-done:   #7faf8a;
}

@media (prefers-color-scheme: light) {
  :root {
    --color-bg: #faf6ee;       /* warm paper */
    --color-text: #1a1712;     /* warm ink */
    --color-muted: #6b6559;
    --color-border: #e6dfd0;
    --color-accent: #c25a00;   /* darker sodium for contrast on light */
    --color-dot-stale:  #9a9283;
    --color-dot-active: #c25a00;
    --color-dot-done:   #4f7a5e;
  }
}

/* ============================================================
   RESET
   ============================================================ */
*, *::before, *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

/* ============================================================
   ELEMENTS — default styling for native HTML
   ============================================================ */
body {
  font-family: var(--font-sans);
  background: var(--color-bg);
  color: var(--color-text);
  line-height: 1.6;
}

h1, h2, h3, h4, h5, h6 {
  line-height: 1.2;
  margin-bottom: var(--space-sm);
}
h1 { font-size: 2rem; }
h2 { font-size: 1.5rem; }
h3 { font-size: 1.25rem; }
h4 { font-size: 1.1rem; }
h5 { font-size: 1rem; }
h6 { font-size: 0.875rem; text-transform: uppercase; letter-spacing: 0.05em; }

p {
  margin-bottom: var(--space-md);
}

small {
  font-size: 0.8125rem;
  color: var(--color-muted);
}

a {
  color: var(--color-accent);
  text-decoration: underline;
  text-underline-offset: 0.15em;
}
a:hover { text-decoration: none; }

ul, ol {
  margin-bottom: var(--space-md);
  padding-left: var(--space-lg);
}
li { margin-bottom: var(--space-xs); }

hr {
  border: 0;
  border-top: 1px solid var(--color-border);
  margin: var(--space-lg) 0;
}

blockquote {
  border-left: 3px solid var(--color-border);
  padding-left: var(--space-md);
  color: var(--color-muted);
  margin-bottom: var(--space-md);
}

code {
  font-family: var(--font-mono);
  font-size: 0.9em;
  background: var(--color-border);
  padding: 0.1em 0.3em;
  border-radius: var(--radius-sm);
}

pre {
  font-family: var(--font-mono);
  background: var(--color-border);
  padding: var(--space-md);
  border-radius: var(--radius-md);
  overflow-x: auto;
  margin-bottom: var(--space-md);
}
pre code {
  background: transparent;
  padding: 0;
}

table {
  width: 100%;
  border-collapse: collapse;
  margin-bottom: var(--space-md);
}
th, td {
  text-align: left;
  padding: var(--space-sm) var(--space-md);
  border-bottom: 1px solid var(--color-border);
}
th { font-weight: 600; }

/* ============================================================
   FORMS — buttons and inputs
   ============================================================ */
button,
input,
textarea,
select {
  font: inherit;
  color: inherit;
}

input[type="text"],
input[type="email"],
input[type="password"],
textarea,
select {
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  padding: var(--space-sm) var(--space-md);
  width: 100%;
  max-width: 20rem;
}

textarea {
  min-height: 5rem;
  resize: vertical;
}

input[type="checkbox"],
input[type="radio"] {
  margin-right: var(--space-xs);
}

label {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  margin-right: var(--space-md);
}

/* ============================================================
   COMPONENTS — project-specific components
   ============================================================ */

/* Brand mark: the sodium-orange dot IS Orbit. No wordmark.
   The dot sizes to its surrounding text via em units, so it
   scales naturally with whatever it sits beside. The brand dot
   is the root of orbit's dot vocabulary — everything orbits it. */
.brand {
  display: inline-block;
  width: 0.75em;
  height: 0.75em;
  border-radius: 50%;
  background: var(--color-accent);
  color: var(--color-accent); /* drives the pulse box-shadow via currentColor */
  flex-shrink: 0;
  vertical-align: 0.08em;
  transition: transform 300ms ease-out;
}

/* Status dots — small sibling of the brand dot. Two tones only:
   .dot (stale grey) and .dot-active (sodium). The discriminator is
   time: a thing is active if it moved in the last 7 days, stale
   otherwise. No "done" tone — completion events just move, then
   decay. Applies to projects, ideas, issues, designs, PRs, and
   history entries. */
.dot {
  display: inline-block;
  width: 0.55em;
  height: 0.55em;
  border-radius: 50%;
  background: var(--color-dot-stale);
  flex-shrink: 0;
  vertical-align: 0.08em; /* nudge up so it optically aligns with x-height */
  transition: transform 300ms ease-out;
}
.dot-active { background: var(--color-dot-active); }
.dot-done   { background: var(--color-dot-done); }

/* Pulse: a concentric ring that radiates out and fades. Used as a
   hover affordance on any dot-shaped element (.dot rows + .brand).
   theme.js adds .is-pulsing on hover and removes it on the next
   animationiteration after hover ends — so every started pulse
   cycle finishes cleanly even after the cursor leaves.
   currentColor drives the ring tone; each dot variant sets its own. */
@keyframes dot-pulse {
  0%   { box-shadow: 0 0 0 0 currentColor; }
  100% { box-shadow: 0 0 0 0.9em transparent; }
}
.is-pulsing {
  transform: scale(1.5);
  animation: dot-pulse 1.2s ease-out infinite;
}

/* For lists where a status dot replaces the default list bullet. */
.dot-list {
  list-style: none;
  padding-left: 0;
}
.dot-list li {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
}

.btn {
  display: inline-block;
  padding: var(--space-sm) var(--space-md);
  background: var(--color-bg);
  color: var(--color-text);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  font: inherit;
  text-decoration: none;
  cursor: pointer;
}
.btn:hover:not(:disabled) {
  border-color: var(--color-accent);
  color: var(--color-accent);
}
.btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* Site header: thin bar with the orbit dot on the left and optional
   right-side actions. Non-sticky; scrolls off with the page. */
.site-header {
  display: flex;
  align-items: center;
  gap: var(--space-md);
  padding: var(--space-md) 0;
  border-bottom: 1px solid var(--color-border);
  margin-bottom: var(--space-lg);
}
.site-header a.brand {
  /* dot is already a brand class; this keeps the dot as a real link */
  cursor: pointer;
}
.site-header-spacer { flex: 1; }
.site-header-actions {
  display: flex;
  align-items: center;
  gap: var(--space-md);
  font-family: var(--font-mono);
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--color-muted);
}
.site-header-actions a:not(.btn) {
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 0.2em;
}
.site-header-actions a:not(.btn):hover { color: var(--color-text); }

/* Section heading: the mono-uppercase-muted treatment reusable on
   real pages. The scaffold's .prototype-section > h2 rule remains
   untouched for the styleguide; this is a separate opt-in class. */
.section-heading {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--color-muted);
  padding-bottom: var(--space-sm);
  margin-bottom: var(--space-md);
  border-bottom: 1px solid var(--color-border);
  font-weight: 400;
}

/* Project row: home-page entry. Grid with a dot-pulse hover. */
.project-row {
  display: grid;
  grid-template-columns: auto minmax(8rem, auto) 1fr auto;
  align-items: baseline;
  gap: var(--space-md);
  padding: var(--space-sm) var(--space-md);
  border-bottom: 1px solid var(--color-border);
  text-decoration: none;
  color: inherit;
}
.project-row:hover { text-decoration: none; }
.project-row:last-child { border-bottom: none; }

/* currentColor is set per-dot-variant so the box-shadow pulse matches
   the dot's own tone. */
.dot            { color: var(--color-dot-stale); }
.dot.dot-active { color: var(--color-dot-active); }
.dot.dot-done   { color: var(--color-dot-done); }
.project-row-name {
  font-weight: 700;
}
.project-row-slug {
  color: var(--color-muted);
  margin-right: var(--space-sm);
}
.project-row-recent {
  color: var(--color-muted);
  font-size: 0.875rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.project-row-recent::before {
  content: "↳ ";
  margin-right: 0.25em;
  opacity: 0.6;
}
.project-row-time {
  color: var(--color-muted);
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
}

/* Entry row: shared shape for every flow-stage row.
   Grid: [dot] [label] [title] [right-meta]. The parent .entry-list
   owns the column widths and rows inherit via subgrid, so all rows
   in a list line up even when labels have different widths. */
.entry-row {
  display: grid;
  grid-template-columns: subgrid;
  grid-column: 1 / -1;
  align-items: baseline;
  padding: var(--space-xs) 0;
}
.entry-row-label {
  color: var(--color-muted);
  font-size: 0.75rem;
  font-family: var(--font-mono);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  white-space: nowrap;
}
.entry-row-title {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.entry-row-title a {
  color: inherit;
  text-decoration: none;
}
.entry-row-title a:hover {
  color: var(--color-accent);
}
.entry-row-meta {
  color: var(--color-muted);
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
}

/* Lists of entry rows: remove native bullets since the leading dot
   element carries the semantic. When the list contains .entry-row
   children, it becomes the grid container so every row within it
   aligns its columns. Other list contents (.project-row lists on
   home) keep their own layout. */
.entry-list {
  list-style: none;
  padding: 0;
  margin: 0 0 var(--space-lg) 0;
}
.entry-list:has(.entry-row) {
  display: grid;
  grid-template-columns: auto auto 1fr auto;
  column-gap: var(--space-md);
}

/* Expandable list section: when a section contains more than ~12
   entries, wrap the overflow in <details class="entry-expand"> so
   readers see a compact "show N more" affordance instead of an
   endless scroll. Styled to look like a continuation of the list. */
.entry-expand {
  margin: 0 0 var(--space-lg) 0;
}
.entry-expand > summary {
  list-style: none;
  cursor: pointer;
  font-family: var(--font-mono);
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--color-muted);
  padding: var(--space-sm) 0;
}
.entry-expand > summary::-webkit-details-marker { display: none; }
.entry-expand > summary::before {
  content: "▸  ";
}
.entry-expand[open] > summary::before {
  content: "▾  ";
}
.entry-expand > summary:hover { color: var(--color-accent); }
.entry-expand > .entry-list {
  margin-top: 0;
}

/* Entry story: a history row that expands to show the PR description.
   The row is a normal .entry-row (direct grid child). The body is a
   sibling li, also a direct grid child, aligned to the title column.
   A click on the row toggles .entry-story-hidden on the body.
   Entries without a body stay as plain .entry-row — no body li. */
.entry-row-expandable {
  cursor: pointer;
}
.entry-story-body {
  grid-column: 3 / -1;
  padding: 0 0 var(--space-md) 0;
  font-size: 0.9rem;
  color: var(--color-muted);
  line-height: 1.5;
}
.entry-story-body p {
  margin: 0 0 var(--space-sm) 0;
}
.entry-story-body p:last-child {
  margin-bottom: 0;
}
.entry-story-body ul,
.entry-story-body ol {
  margin: 0 0 var(--space-sm) 0;
  padding-left: var(--space-lg);
}
.entry-story-body h3 {
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--color-text);
  margin: var(--space-md) 0 var(--space-xs) 0;
}
.entry-story-body code {
  font-size: 0.85em;
}
.entry-story-link {
  font-size: 0.8rem;
  color: var(--color-muted);
  text-decoration: none;
}
.entry-story-link:hover {
  color: var(--color-accent);
}
.entry-story-hidden {
  display: none;
}

/* Meta strip: one line of mono, muted metadata shown under a page
   h1 (forgejo link, last-activity, project id, etc.). */
.meta-strip {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-md);
  font-family: var(--font-mono);
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--color-muted);
  margin-bottom: var(--space-lg);
}
.meta-strip a {
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 0.2em;
}
.meta-strip a:hover { color: var(--color-text); }

/* Day divider: separates history entries when the date changes. */
.day-divider {
  display: flex;
  align-items: center;
  gap: var(--space-md);
  font-family: var(--font-mono);
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--color-muted);
  margin: var(--space-md) 0 var(--space-sm) 0;
}
.day-divider::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--color-border);
}
