/* ==========================================================================
   simplicated — the one stylesheet, shared by the portfolio index and by
   every app on every subdomain.

   An app never adds structural CSS. It sets the custom properties below in
   apps/<slug>/theme.css, which loads after this file and wins. That is the
   whole theming system.
   ========================================================================== */

:root {
  color-scheme: light dark;

  /* --- surfaces ------------------------------------------------------- */
  --bg: #fbfaf7;
  --fg: #1b1a18;
  --muted: #6f6b64;
  --rule: #e4e0d7;

  /* --- the one colour an app usually wants to change ------------------- */
  --accent: #1b1a18;
  --accent-fg: #fbfaf7;

  /* --- type ------------------------------------------------------------ */
  --font-heading: ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-body: ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;

  /* --- measure --------------------------------------------------------- */
  --measure: 36rem;
  --radius: 12px;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #161513;
    --fg: #eceae5;
    --muted: #948f86;
    --rule: #2d2a26;
    --accent: #eceae5;
    --accent-fg: #161513;
  }
}

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

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

/* An image is the one element that can wreck the layout on its own: with no
   rule of its own it lays out at its full pixel width and pushes the column
   sideways. This is the floor, so a shot added without a matching component
   still fits the measure. */
img {
  max-width: 100%;
  height: auto;
}

body {
  margin: 0;
  padding: 4.5rem 1.5rem 3rem;
  background: var(--bg);
  color: var(--fg);
  font-family: var(--font-body);
  font-size: 1rem;
  line-height: 1.65;
  display: flex;
  justify-content: center;
  -webkit-font-smoothing: antialiased;
}

main {
  width: 100%;
  max-width: var(--measure);
}

/* --- type ------------------------------------------------------------- */

h1,
h2,
h3 {
  font-family: var(--font-heading);
  font-weight: 600;
  letter-spacing: -0.02em;
  text-wrap: balance;
}

h1 {
  margin: 0 0 0.35rem;
  font-size: 2rem;
  line-height: 1.15;
}

h2 {
  margin: 2.75rem 0 0.6rem;
  font-size: 1.125rem;
  letter-spacing: -0.01em;
}

h3 {
  margin: 1.75rem 0 0.35rem;
  font-size: 1rem;
  letter-spacing: 0;
}

p {
  margin: 0 0 1rem;
  text-wrap: pretty;
}

a {
  color: inherit;
  text-decoration-color: var(--rule);
  text-underline-offset: 0.15em;
}

a:hover {
  text-decoration-color: currentColor;
}

hr {
  margin: 2.5rem 0;
  border: 0;
  border-top: 1px solid var(--rule);
}

/* Standfirst under an h1. */
.tagline {
  margin: 0;
  color: var(--muted);
  font-size: 1.0625rem;
}

/* A small caps label above a list or a block. */
.label {
  margin: 2.75rem 0 0.9rem;
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--muted);
}

/* The "last updated" line on a legal page. */
.updated {
  margin: 0 0 2.25rem;
  font-size: 0.875rem;
  color: var(--muted);
}

.lede {
  margin-bottom: 2.25rem;
  color: var(--muted);
}

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

.hero {
  display: flex;
  align-items: center;
  gap: 1.1rem;
  margin-bottom: 1.75rem;
}

.appicon {
  flex: none;
  width: 84px;
  height: 84px;
  border-radius: 22.5%;
  border: 1px solid var(--rule);
  object-fit: cover;
}

/* --- call to action --------------------------------------------------- */

.cta-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  margin: 0 0 2.5rem;
}

.cta {
  display: inline-block;
  padding: 0.6rem 1.15rem;
  border: 1px solid transparent;
  border-radius: 999px;
  background: var(--accent);
  color: var(--accent-fg);
  font-size: 0.9375rem;
  font-weight: 550;
  text-decoration: none;
  white-space: nowrap;
}

.cta:hover {
  opacity: 0.85;
}

/* The second action in a row, when there is one. Outlined rather than filled,
   so a page with two places to go still has an obvious first one. */
.cta--ghost {
  background: none;
  border-color: var(--rule);
  color: var(--fg);
}

.cta--ghost:hover {
  opacity: 1;
  border-color: var(--muted);
}

/* Same shape, but not a link — for an app that hasn't shipped yet. */
.cta--pending {
  background: none;
  border-color: var(--rule);
  color: var(--muted);
  font-weight: 400;
  cursor: default;
}

.cta--pending:hover {
  opacity: 1;
}

/* --- ruled link list -------------------------------------------------- */

.index {
  margin: 0;
  padding: 0;
  list-style: none;
}

.index li {
  border-top: 1px solid var(--rule);
}

.index li:last-child {
  border-bottom: 1px solid var(--rule);
}

.index a {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1.5rem;
  padding: 0.9rem 0;
  text-decoration: none;
}

.index a:hover .index-name {
  text-decoration: underline;
  text-underline-offset: 0.15em;
}

.index-name {
  font-weight: 500;
}

.index-note {
  flex: 1 1 auto;
  min-width: 0;
  color: var(--muted);
  font-size: 0.875rem;
  text-align: right;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* --- feature list ----------------------------------------------------- */

.points {
  margin: 0 0 1rem;
  padding: 0;
  list-style: none;
}

.points li {
  position: relative;
  padding-left: 1.15rem;
  margin-bottom: 0.5rem;
}

.points li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.72em;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--muted);
}

/* --- screenshot strip ------------------------------------------------- */

.shots {
  display: flex;
  /* Without this a flex row stretches an auto-height image to match the
     tallest one, which distorts a strip that mixes phone and watch shots. */
  align-items: flex-start;
  gap: 0.85rem;
  margin: 0 0 1rem;
  padding-bottom: 0.75rem;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  overscroll-behavior-x: contain;
}

.shots img {
  flex: none;
  width: 190px;
  height: auto;
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  scroll-snap-align: start;
}

/* --- desktop screenshots ----------------------------------------------- */

/* A Mac window is landscape: at the strip's 190px it would be an unreadable
   smudge, so these stack down the measure instead. Same border as the strip,
   and it earns its keep here — an app themed after its own window shares the
   page's background, so without an edge the screenshot dissolves into it. The
   shot must be the whole window, ending on its own bottom edge; a capture cut
   off mid-sentence reads as a broken image rather than a scrolled document. */
.shots-window {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1.25rem;
  margin: 0 0 1rem;
}

/* The first shot carries the detail. The rest pair off beside it at half the
   width, which reads as "and here is the other view" instead of three
   identical slabs stacked down the page. */
.shots-window figure:first-child {
  grid-column: 1 / -1;
}

.shots-window figure {
  margin: 0;
}

.shots-window img {
  display: block;
  width: 100%;
  height: auto;
  border: 1px solid var(--rule);
  border-radius: var(--radius);
}

.shots-window figcaption {
  margin-top: 0.55rem;
  color: var(--muted);
  font-size: 0.875rem;
  line-height: 1.5;
}

/* --- questions and answers -------------------------------------------- */

.qa {
  margin: 0;
}

.qa dt {
  margin-top: 1.6rem;
  font-weight: 550;
}

.qa dd {
  margin: 0.25rem 0 0;
  color: var(--muted);
}

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

.sitefoot {
  margin-top: 3.5rem;
  padding-top: 1.4rem;
  border-top: 1px solid var(--rule);
  font-size: 0.875rem;
  color: var(--muted);
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 0.9rem;
}

/* --- single-message page (404) ---------------------------------------- */

body.centered {
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-height: 100svh;
  padding-top: 1.5rem;
  text-align: center;
}

/* --- narrow screens --------------------------------------------------- */

@media (max-width: 32rem) {
  body {
    padding-top: 3rem;
  }

  h1 {
    font-size: 1.75rem;
  }

  .index a {
    flex-direction: column;
    gap: 0.15rem;
  }

  .index-note {
    text-align: left;
  }

  /* Half of a phone's width is no width at all for a Mac window. */
  .shots-window {
    grid-template-columns: 1fr;
  }
}
