/* ticer.co — personal hub.
   Deliberately quiet: this page is a doorway, not a frame. Each app page
   beyond it keeps its own identity (Pleat is paper + coral, FileSift is
   paper + blue), so the hub stays neutral and typographic and never
   competes with what it links to.

   No webfonts — nothing to load, nothing to fail. */

:root {
  /* A warm neutral that sits between FileSift's #FAF9F7 and Pleat's
     #F7F5EE, so arriving at either app page is not a jolt. */
  --paper: #FAF8F4;
  --surface: #FFFFFF;
  --ink: #1A1815;
  --ink-soft: #57534B;
  --ink-faint: #8A8378;
  --line: #E6E1D8;
  --hover: #F2EEE6;

  --maxw: 720px;
  --radius: 14px;

  --font: -apple-system, BlinkMacSystemFont, "SF Pro Text", system-ui,
          "Segoe UI", Roboto, sans-serif;
  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
}

@media (prefers-color-scheme: dark) {
  :root {
    --paper: #131211;
    --surface: #1B1A18;
    --ink: #F4F1EA;
    --ink-soft: #B5B0A6;
    --ink-faint: #857F74;
    --line: #2E2B26;
    --hover: #201E1B;
  }
}

* { box-sizing: border-box; margin: 0; padding: 0; }

body {
  font-family: var(--font);
  background: var(--paper);
  color: var(--ink);
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

a { color: inherit; text-decoration: none; }

.wrap { max-width: var(--maxw); margin: 0 auto; padding: 0 24px; }

/* The name, set as a letterspaced wordmark. The trailing letter-space is
   given back with a negative margin so it optically aligns left. */
.wordmark {
  font-size: 13px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.18em;
  margin-right: -0.18em;
  color: var(--ink);
}

/* ---- header ---- */
header.site { padding: 40px 0 0; }

/* ---- hero ---- */
.hero { padding: 56px 0 64px; }
.hero h1 {
  font-size: clamp(30px, 5.2vw, 42px);
  font-weight: 600;
  letter-spacing: -0.022em;
  line-height: 1.14;
  max-width: 17ch;
  /* Without this the last line is left with a stub ("making apps."); balance
     splits the headline evenly instead. Degrades to normal wrapping. */
  text-wrap: balance;
}
.hero p {
  margin-top: 20px;
  font-size: 17px;
  color: var(--ink-soft);
  max-width: 46ch;
}

/* ---- app list ----
   One row per app. Adding an app is adding one <a class="app"> — the grid
   and the hairline rules take care of themselves. */
.apps {
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}

.app {
  position: relative;
  display: grid;
  grid-template-columns: 52px 1fr auto auto;
  align-items: center;
  gap: 20px;
  padding: 22px 16px;
  margin: 0 -16px;
  border-radius: var(--radius);
  transition: background .15s ease;
}
.app:hover { background: var(--hover); }

/* Dividers are drawn between rows rather than as a border on each, so the
   hover wash can be rounded on all four corners without a rule cutting
   across it. The 16px inset cancels the row's negative margin, putting the
   hairline flush with the list's content edge — and with .apps' top rule. */
.app + .app::before {
  content: "";
  position: absolute;
  top: 0;
  left: 16px;
  right: 16px;
  height: 1px;
  background: var(--line);
}

.app-icon {
  width: 52px;
  height: 52px;
  border-radius: 12px;
  display: block;
  /* Several of these icons carry their own light background; a hairline
     keeps them from bleeding into the paper. */
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .07);
}
@media (prefers-color-scheme: dark) {
  .app-icon { box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .09); }
}

.app-text { min-width: 0; }
.app-text h2 {
  font-size: 20px;
  font-weight: 600;
  letter-spacing: -0.01em;
  line-height: 1.25;
}
.app-text p {
  margin-top: 3px;
  font-size: 15px;
  color: var(--ink-soft);
  line-height: 1.45;
  /* These lines all land just over one line at desktop width; without this
     each one wraps to a single orphan word. */
  text-wrap: pretty;
}

/* Metadata set in mono — precise and quiet, and it reads as a different
   kind of information than the prose beside it. */
.app-meta {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-faint);
  text-align: right;
  white-space: nowrap;
  line-height: 1.5;
}
.app-meta .status { display: block; color: var(--ink-soft); }

.app-arrow {
  width: 18px;
  height: 18px;
  stroke: var(--ink-faint);
  stroke-width: 1.75;
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: transform .15s ease, stroke .15s ease;
}
.app:hover .app-arrow { stroke: var(--ink); }
/* Internal links travel right; external links travel up and out. The two
   arrows say where you are about to end up. */
.app:hover .app-arrow.internal { transform: translateX(3px); }
.app:hover .app-arrow.external { transform: translate(2px, -2px); }

@media (max-width: 560px) {
  .app {
    grid-template-columns: 44px 1fr auto;
    /* Row gap is 0 — the meta line carries its own margin-top, so the two
       stacked rows don't compound into an oversized gap. */
    column-gap: 14px;
    row-gap: 0;
    padding: 20px 12px;
    margin: 0 -12px;
  }
  .app + .app::before { left: 12px; right: 12px; }
  .app-icon { width: 44px; height: 44px; border-radius: 10px; }
  .app-text h2 { font-size: 18px; }
  .app-text p { font-size: 14px; }
  /* The meta column is the first thing to go; status moves under the
     name so the row never wraps into an awkward three-line block. */
  .app-meta { grid-column: 2; grid-row: 2; text-align: left; margin-top: 6px; }
  .app-meta .status { display: inline; }
  .app-meta .platform::after { content: " ·"; }
  .app-arrow { grid-column: 3; grid-row: 1; }
}

/* ---- footer ---- */
footer.site {
  /* Just enough to separate the list's bottom rule from the footer's top
     rule; more than this and the empty span between them reads as a
     missing element rather than breathing room. */
  margin-top: 40px;
  padding: 28px 0 56px;
  border-top: 1px solid var(--line);
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 20px;
  font-size: 13px;
  color: var(--ink-faint);
}
footer.site a:hover { color: var(--ink); }
@media (max-width: 480px) {
  footer.site { flex-direction: column; gap: 8px; }
}

/* ---- focus ---- */
a:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 3px;
  border-radius: 6px;
}

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