

/* Kill double-tap-to-zoom globally while keeping pinch-zoom for
   accessibility. Every tap on a button / link / video theater /
   stepper used to trigger ios zoom on a rapid second tap. manipulation
   allows scroll + pinch-zoom but disables the double-tap gesture. */
html, body { touch-action: manipulation; }

/* Smooth scroll for in-page anchor jumps. Honors prefers-reduced-motion. */
html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

/* Tighter "surgical" radius scale — overrides the default scale in
   @elements/style. The defaults read a touch too rounded for our
   chrome; pulling each token down a notch keeps the geometry
   present but less pillowy. */
:root {
  --radius-xs:  2px;
  --radius-sm:  3px;
  --radius-md:  4px;
  --radius-lg:  5px;
  --radius-xl:  7px;
  --radius-2xl: 9px;

  /* App-specific container for form-shaped pages (purchase, account
     settings). Narrower than --container-marketing so multi-section
     forms read as a single column without inputs that stretch to the
     limits of marketing-page width. /signin and /signup keep their
     own --container-narrow shell (~480px) — those are short forms. */
  --container-form: 40rem;   /* 640px */
}

/* iOS Safari's auto-zoom on focus for inputs is killed globally
   via the viewport meta tag's `maximum-scale=1` (see
   app/shared/templates/shared-head). That replaces the prior approach of
   forcing every input to font-size:16px. */

/* elements.dev brand voice: sky-blue accent, Inter for everything,
   JetBrains Mono reserved for actual code. The font stacks themselves
   are wired in ./fonts.css; here we just point the design-system
   tokens at them.

   Type rule:
     --font-sans → Inter → titles, body, chrome, buttons, labels
     --font-mono → JetBrains Mono → fenced code, inline code, terminal, kbd

   Brand voice:
     --accent      → blue           (vs ink in customer default)
     --accent-deep → blue-dark      (hover, link color)
     --accent-soft → blue-light     (focus wash, callout backdrops) */

:root {
  --font-sans:
    "Inter",
    system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI",
    Roboto, Helvetica, Arial, sans-serif;
  --font-mono:
    "JetBrains Mono",
    ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;

  --accent:       var(--blue);
  --accent-deep:  var(--blue-dark);
  --accent-soft:  var(--blue-light);
  --accent-dot:   var(--blue-dot);
  --accent-wash:  var(--blue-wash);

  /* Tighten default `<button>` height app-wide. Framework default is
     2.75rem (44px) — read as "comically large" once we stripped the
     rest of the chrome from the action-row kebabs. Default to 36px
     (matches the framework's `.is-sm` modifier); explicit `.is-lg`
     / `.is-hero` consumers still scale up. Padding stays at the
     framework default but font-size shrinks a tick for proportion. */
  --button-height:    2.25rem;
  --button-font-size: 0.8125rem;

  /* ─── Kind chip palette ─────────────────────────────────────────
     Single source of truth for the chip color of every content
     kind. Mirrors `KindColor` in app/lib/enums.ts — change a hex
     here AND there together. Surfaces that render kind chips (feed
     row, palette, post byline, search results, profile rows, the
     feed-digest email's inline styles) all read these values.

     Tone: soft / pastel — lower saturation than Tailwind 600. Hue
     separation per kind is the dominant signal; the chips
     themselves don't shout.

     Locked rules (don't reshuffle without asking):
       - never red / green / brown for content kinds (status-coded)
       - hue per kind never collapses with another kind */

  /* Post kinds — pigment-named editorial palette. Mirror of
     KindColor in app/lib/enums.ts. */
  --kind-discuss:   #7BA89B;   /* eucalyptus      */
  --kind-show:      #D58475;   /* coral           */
  --kind-ask:       #7995B6;   /* denim           */
  --kind-announce:  #DBB05A;   /* goldenrod       */
  --kind-teach:     #A07A96;   /* plum            */
  /* Other content kinds (parallel set on the chip axis) */
  --kind-course:    #D77F9E;   /* rose            */
  --kind-lesson:    #D77F9E;   /* same as course — a lesson reads as course-scoped */
  --kind-guide:     #A899C5;   /* lilac           */
  --kind-video:     #DD9474;   /* peach           */
  /* Neutrals — content kinds that don't carry a strong semantic
     hue (comment / user are about the actor, not the content
     type; page is structural). */
  --kind-comment:   #94a3b8;   /* slate           */
  --kind-user:      #94a3b8;   /* slate           */
  --kind-page:      #9ca3af;   /* gray            */
  /* Defensive fallback — the generic "post" chip should not
     normally render (post hits surface their actual postKind), but
     keep a value on hand for any caller that emits "post". */
  --kind-post:      var(--kind-discuss);

  /* Issue tracker kinds — bug + feature carry the status signal
     directly (red FOR bug is the entire point; navy reads as
     steady-progress for feature). The red/green/brown lockout that
     applies to every other content kind doesn't apply here.
     Mirror in app/lib/enums.ts (KindColor) when adjusting. */
  --kind-bug:       #9b1c1c;   /* deep red        */
  --kind-feature:   #1e4d8c;   /* navy            */
}

/* Per-kind chip color rules — applied wherever a kind label needs
   tinting (ContentItem's kind label, post byline, search palette,
   etc.). Class names follow the pattern `.kind--<key>` so consumers
   pass `kindClass="kind--bug"` and the visible kind tint resolves
   automatically. The earlier `.eyebrow--*` per-page convention is
   preserved by the rules in feed-row + post-meta; new surfaces use
   `.kind--*` going forward. */
.kind--discuss   { color: var(--kind-discuss);  }
.kind--show      { color: var(--kind-show);     }
.kind--ask       { color: var(--kind-ask);      }
.kind--announce  { color: var(--kind-announce); }
.kind--teach     { color: var(--kind-teach);    }
.kind--course    { color: var(--kind-course);   }
.kind--lesson    { color: var(--kind-lesson);   }
.kind--guide     { color: var(--kind-guide);    }
.kind--video     { color: var(--kind-video);    }
.kind--comment   { color: var(--kind-comment);  }
.kind--user      { color: var(--kind-user);     }
.kind--page      { color: var(--kind-page);     }
.kind--bug       { color: var(--kind-bug);      }
.kind--feature   { color: var(--kind-feature);  }

/* Shared page hero — h1 + paragraph subtitle, one rule used by every
   top-level page (install, pricing, etc.). Page-specific CSS only
   tweaks margins/width around this; size and weight come from here. */
.page-hero { margin-bottom: var(--space-6); }

.page-hero-title {
  font-family: var(--font-sans);
  font-weight: var(--font-bold);
  font-size: var(--text-3xl);    /* 56px per brand spec */
  letter-spacing: var(--tracking-tight);
  line-height: var(--leading-tight);
  margin: 0 0 var(--gap-head-sub);
  color: var(--ink);
}

.page-hero-sub {
  font-family: var(--font-sans);
  font-size: var(--text-md);     /* 18px */
  color: var(--ink-soft);
  line-height: var(--leading-body);
  margin: 0;
  max-width: 36rem;
}
.page-hero-sub code {
  font-family: var(--font-mono);
  font-size: 0.875em;
  background: var(--bg-panel);
  padding: 0.0625rem 0.375rem;
  border-radius: var(--radius-xs);
  color: var(--ink);
}

@media (max-width: 700px) {
  html .install-title,
  html .auth-title,
  html .account-title,
  html .learn-title,
  html .issues-h1,
  html .page-hero-title,
  html .purchase-main .page-head h1 {
    font-size:   2.5rem;          /* 40px on mobile — h1 collapses one step */
    line-height: 1.1;
  }

  /* Home hero — fluid clamp() handles mobile + desktop in one rule
     in app/pages/home/style.css; no mobile override needed. */

  /* Uniform 1.5rem horizontal gutter across every page on mobile. */
  .shell-narrow,
  .shell-prose,
  .shell-marketing,
  .shell-wide {
    padding-left:  1.5rem;
    padding-right: 1.5rem;
  }
}

/* ─── Canonical page hero (forced) ────────────────────────────────
   Every top-level page (/feed, /install, /learn, /docs, /pricing)
   uses the same shell width, the same hero top spacing, and the
   same h1 typography. Forced with !important so per-page stylesheets
   loaded after this file can't drift. Single source of truth. */

.feed-page-shell,
.install-shell,
.learn-shell,
.docs-page-shell,
.pricing-shell,
.courses-show-shell,
.courses-index-shell,
.post-shell,
.courses-lesson-inner,
.search-shell,
.profile-shell,
.notifications-page .shell,
.issues-shell,
.settings-shell {
  max-width: var(--container-marketing) !important;
  margin: 0 auto !important;
  padding: 0 var(--space-8) !important;
}

/* /purchase keeps the narrower 640px column — it's a focused
   checkout form, not a multi-section settings surface. */
.purchase-shell {
  max-width: var(--container-form) !important;
  margin: 0 auto !important;
  padding: 0 var(--space-8) !important;
}

@media (max-width: 700px) {
  .feed-page-shell,
  .install-shell,
  .learn-shell,
  .docs-page-shell,
  .pricing-shell,
  .purchase-shell,
  .courses-show-shell,
  .courses-index-shell,
  .post-shell,
  .courses-lesson-inner,
  .search-shell,
  .profile-shell,
  .notifications-page .shell,
  .issues-shell,
  .settings-shell { padding: 0 var(--space-5) !important; }
}

@media (max-width: 640px) {
  .feed-page-shell,
  .install-shell,
  .learn-shell,
  .docs-page-shell,
  .pricing-shell,
  .purchase-shell,
  .courses-show-shell,
  .courses-index-shell,
  .post-shell,
  .courses-lesson-inner,
  .search-shell,
  .profile-shell,
  .notifications-page .shell,
  .issues-shell,
  .account-settings-page .shell { padding: 0 var(--space-4) !important; }
}

/* Tighter mobile inset for content reader pages — claw back the
   left/right gutters that were burning real estate on phones. */
@media (max-width: 480px) {
  .courses-show-shell,
  .post-shell,
  .courses-lesson-inner,
  .search-shell { padding: 0 var(--space-3) !important; }
}

.feed-page-hero,
.docs-page-hero,
.issues-hero {
  padding: 0 !important;
  margin-bottom: 2.5rem !important;
}

/* Inter has a larger descent than ascent, so text inside a flex-
   centered button visibly floats ABOVE the geometric center even
   with align-items: center + line-height: 1. The button height is
   fixed (height: var(--button-height)), and box-sizing: border-box
   means asymmetric padding-top shrinks the content area — flex
   centering inside that smaller area pulls the text DOWN by half
   the difference. 2px does it without a perceptible height change. */
button, .button { padding-top: 2px; padding-bottom: 0; }

/* Tighten @elements/style's --shadow-soft (10px blur drop shadow)
   site-wide. It reads as too dramatic on inline form fields. Hover
   gets no shadow at all — the border already darkens via
   --input-border-hover. Focus gets a tight 2px accent-wash ring;
   the brand-blue border stays. Applies to bare form controls
   (<input>, <textarea>, <select>) since @elements/style now auto-
   styles them at zero specificity. */
input:hover:not(:disabled):not(:focus),
textarea:hover:not(:disabled):not(:focus),
select:hover:not(:disabled):not(:focus) {
  box-shadow: none;
}
input:focus, input:focus-visible,
textarea:focus, textarea:focus-visible,
select:focus, select:focus-visible {
  /* Framework's :where() :focus rule paints `background: --blue-light`
     and `box-shadow: --shadow-soft`. Both read as notification chrome
     instead of focus, and the halo competes with the cursor. Override:
     white background; only the existing 1px border-color shift to
     --accent indicates focus. No drop shadow, no outer ring. */
  background: var(--bg);
  box-shadow: none;
}

.feed-page-h1,
.install-h1,
.learn-h1,
.docs-page-h1,
.pricing-h1,
.purchase-h1,
.account-h1,
.auth-title,
.search-title,
.notifications-page h1,
.account-settings-page h1,
.profile-name,
.courses-index-h1,
.issues-h1 {
  font-family: var(--font-sans) !important;
  font-weight: var(--font-bold) !important;
  /* Canonical top-level h1: 48px desktop, 40px on phones. Matches
     the home hero so a user navigating between /home, /install,
     /pricing, /account, etc. sees a single page-title scale. */
  font-size: 3rem !important;
  letter-spacing: -0.02em !important;
  line-height: 1 !important;
  color: var(--ink) !important;
  margin: 2rem 0 var(--space-4) !important;
}

/* Content show pages — post / course / lesson titles get a smaller
   hero size than top-level destinations. The CONTENT is the focus
   on these pages; an oversized title competes with the body. 2.5rem
   gives the title enough weight to anchor the page without dominating. */
.post-title,
.courses-show-title,
.courses-lesson-title {
  font-family: var(--font-sans) !important;
  font-weight: var(--font-bold) !important;
  font-size: 2.5rem !important;
  letter-spacing: -0.02em !important;
  line-height: 1.1 !important;
  color: var(--ink) !important;
  margin: 2rem 0 var(--space-4) !important;
}

@media (max-width: 640px) {
  /* Page-h1 on mobile = 40px (2.5rem), matching the home hero's
     floor in app/pages/home/style.css. The hero allows wrap to
     two lines on narrow phones ("The stack for / web apps."),
     which keeps it visually larger than a single-line inner page
     title (Install. / Settings. / etc.) at the same font size. */
  .feed-page-h1,
  .install-h1,
  .learn-h1,
  .docs-page-h1,
  .pricing-h1,
  .purchase-h1,
  .account-h1,
  .auth-title,
  .search-title,
  .notifications-page h1,
  .account-settings-page h1,
  .profile-name,
  .courses-index-h1,
  .issues-h1,
  .post-title,
  .courses-show-title,
  .courses-lesson-title { font-size: 2.5rem !important; margin-top: 1.5rem !important; }
}

.feed-page-lede,
.install-lede,
.docs-page-lede,
.pricing-lede,
.purchase-lede,
.issues-lede,
.notifications-page .lede,
.account-settings-page .lede {
  font-family: var(--font-sans) !important;
  font-size: 0.9375rem !important;
  color: var(--ink-soft) !important;
  line-height: 1.6 !important;
  max-width: 34rem !important;
  /* margin intentionally NOT forced — each page controls its own
     bottom spacing to the next element. Defaults to var(--space-7)
     for breathing room; pages override as needed. */
  margin: 0 0 var(--space-7);
}

/* ─── ElementsBadge — staff-author attribution mark ───────────────
   Lightweight outlined "ELEMENTS" pill rendered next to a byline
   when the author is an Elements staff member. Border-only so it
   reads quiet against text; --accent color locks the brand
   association regardless of context. Sized via em so it tracks the
   surrounding byline scale. Single source of truth — restyles live
   in this rule. */

.elements-pill {
  /* Mirrors the proportions of the existing .feed-page-toolbar .chip
     (rendered cleanly elsewhere on the site) so centering behaves
     consistently with the rest of the chrome. */
  display: inline-flex;
  align-items: center;
  margin-left: 0.4rem;
  padding: 2px 5px;
  border-radius: 3px;
  color: var(--accent-deep);
  background: var(--accent-soft);
  font-family: var(--font-sans);
  font-size: 0.625rem;
  font-weight: var(--font-bold);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  line-height: 1;
  white-space: nowrap;
  flex-shrink: 0;
  vertical-align: 1px;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
