/* Hallmark · route: custom (tuned) · macrostructure: Index-First · nav: none (masthead is the identity) · footer: three-column support/privacy/studio
 * vibe: "calm, exact, small; sunlit shore, evening shore in dark"
 * paper: oklch(96.5% 0.014 82) sand · ink: oklch(25% 0.04 225) sea · accent: oklch(64% 0.15 42) low sun
 * display: Young Serif (OFL) · body: Hanken Grotesk (OFL), both self-hosted
 * axes: light / roman-serif / warm · idea: "the sun resting on a horizon rule" · enrichment: none (typography + one CSS mark)
 * pre-emit critique: P4 H4 E4 S4 R5 V4
 */

/* Tokens and base: see base.css (linked before this file). */
/* ---------- Masthead ---------- */
.masthead {
  display: grid;
  gap: var(--space-lg);
  padding-block: var(--space-2xl) var(--space-lg);
}

.wordmark {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: var(--text-display);
  line-height: var(--leading-display);
  letter-spacing: -0.02em;
  overflow-wrap: anywhere; /* wraps only when the column cannot hold it: 200% text zoom, no-font fallback */
  min-width: 0;
}
.wordmark a { text-decoration: none; }
/* The studio mark stacked above the name, like the crest on a hotel card. px: an image, not text. */
.wordmark__mark {
  width: 48px;
  height: 48px;
  margin-bottom: var(--space-sm);
}
@media (max-width: 47.99rem) {
  /* Phone: the mark is larger and centered over the centered name, matching the app pages' top bar */
  .wordmark { text-align: center; }
  .wordmark__mark { width: 64px; height: 64px; margin-inline: auto; }
}

.intro {
  display: grid;
  gap: var(--space-sm);
  align-content: end;
}
.intro__line {
  font-size: var(--text-lead);
  line-height: var(--leading-lead);
  color: var(--color-ink);
}
.intro__meta {
  color: var(--color-ink-2);
}
.intro__meta a { color: var(--color-sea); text-decoration-color: currentColor; }

@media (min-width: 80rem) {
  .masthead {
    grid-template-columns: minmax(0, 1fr) var(--col-side);
    align-items: end;
    gap: var(--space-xl);
    padding-block: var(--space-3xl) var(--space-xl);
  }
  .wordmark__mark { width: 64px; height: 64px; }
}

/* Horizon and footer: see components.css (linked between base.css and this file). */

/* ---------- App index ---------- */
/* Rules sit only between rows; the horizon opens the list and the footer rule closes it, so no
   two rules ever stack. The last row's own padding is its distance to the footer rule, the same
   distance a row keeps to the divider below it. */
.apps { padding-block: var(--space-md) 0; }

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

/* Each row is two parts. The head (icon, name, line, cue) is one link to the app's own page: the
   name's link stretches over the whole head, so it is one tab stop and one large tap target. The
   meta (status and store, support, privacy links) sits outside the head, so no link nests in another. */
.app {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  row-gap: var(--space-sm);
  padding-block: var(--space-md);
}
.app + .app { border-top: var(--rule) solid var(--color-rule); }

/* Icon sizes are px on purpose: an app icon is an image, not text, so it must not grow with text
   zoom and squeeze the name column (at 200% a 4rem rail broke "Photo" mid-word). */
.app__head {
  position: relative;
  display: grid;
  grid-template-columns: 64px minmax(0, 1fr);
  column-gap: var(--space-sm);
}
.app__icon {
  width: 64px;
  height: 64px;
  border-radius: var(--radius-icon);
}
/* minmax(0, 1fr): an untemplated grid track grows to its widest child and pushes past a phone edge */
.app__text { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--space-3xs); align-content: center; justify-items: start; }

.app__name {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: var(--text-title);
  line-height: var(--leading-title);
  letter-spacing: -0.01em;
  overflow-wrap: anywhere;
}
.app__name a { text-decoration-thickness: var(--rule); text-underline-offset: 0.18em; }
.app__name a:hover { text-decoration-color: var(--color-sun); }

/* The stretched link: its box covers the head, so the icon, line and cue all open the app page.
   iOS would flash its grey tap box over the whole head; the cue's own pressed state replaces it. */
.app__open { -webkit-tap-highlight-color: transparent; }
.app__open::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: var(--space-xs);
}
.app__open:focus-visible { outline: none; }
.app__open:focus-visible::after {
  outline: 2px solid var(--color-focus);
  outline-offset: var(--space-2xs);
}

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

/* The cue: an app-style button that says where the row goes, shown at rest so touch needs no hover.
   Decorative to screen readers; the link itself carries the name and, for an outside site, its address. */
.app__cue {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3xs);
  margin-top: var(--space-xs);
  padding: var(--space-3xs) var(--space-xs) var(--space-3xs) var(--space-sm);
  border-radius: 999px;
  background: color-mix(in oklch, var(--color-sea) 14%, var(--color-paper));
  color: var(--color-sea);
  font-weight: var(--weight-strong);
  max-width: 100%; /* wraps inside the button only when the column cannot hold it (200% text) */
  transition: background-color var(--dur-quick) var(--ease-out);
}
.app__cue-icon {
  flex: none; /* never squeezed out when the words wrap */
  width: 1em;
  height: 1em;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.75;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.app__head:hover .app__cue,
.app__head:has(.app__open:focus-visible) .app__cue { background: color-mix(in oklch, var(--color-sea) 24%, var(--color-paper)); }
.app__head:active .app__cue { background: color-mix(in oklch, var(--color-sea) 32%, var(--color-paper)); }

/* Status above links at every width, so every row has one shape whatever its link count */
.app__meta {
  display: grid;
  justify-items: start;
  gap: var(--space-xs);
}

/* Status is plain words; the sea colour repeats what the words say, so colour is never the only signal. */
.status { color: var(--color-muted); }
.status--live { color: var(--color-sea); }

.links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2xs) var(--space-md);
  font-weight: var(--weight-strong);
}
/* 44px-plus tap height without moving the text: padding grows the hit area, the negative margin gives the space back */
.links a {
  display: inline-block;
  white-space: nowrap;
  padding-block: var(--space-xs);
  margin-block: calc(-1 * var(--space-xs));
}

@media (min-width: 48rem) {
  .app__head { grid-template-columns: 88px minmax(0, 1fr); column-gap: var(--space-md); }
  .app__icon { width: 88px; height: 88px; }
}
@media (min-width: 80rem) {
  .apps { padding-block: var(--space-lg) 0; }
  .app {
    grid-template-columns: minmax(0, 1fr) var(--col-side);
    align-items: center;
    column-gap: var(--space-lg);
    padding-block: var(--space-lg);
  }
  .app__head { align-items: center; column-gap: var(--space-lg); }
}

/* ---------- Footer: home-only placement (the footer itself is in components.css) ---------- */
@media (min-width: 80rem) {
  .foot__col--support { padding-left: calc(88px + var(--space-lg)); } /* under the app names */
}

/* ---------- 404 ---------- */
h1.intro__line { font-weight: var(--weight-body); }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition: none !important; }
}
