/* Generated from style.css; do not edit. */
@scope ([data-page-content]) {
/* noriagentic.com — page styles on top of design-tokens.css (nori-design skill).
   Load order: fonts.css → design-tokens.css → style.css → animations.css.

   The page is composed against the v3 anatomy: a .frame graph-rule canvas with
   rails, .sect sections that cross those rails with a + mark, the mono H1,
   and the canonical .belt-* system. Component recipes live in design-tokens.css
   and are never re-implemented here — this sheet only places them.

   Flat structure: hairlines and ramp steps only. There is no light theme. */

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

html { scroll-behavior: smooth; }

:scope {
  /* The fold law needs a known nav height to subtract. Kept in sync with
     .nav-inner padding by test-homepage-v3.py, which fails if the fold drifts
     outside 90–95vh. */
  --nav-h: 56px;
  --gutter: 60px;
  /* Height the v4 logo row occupies under the fold: its own top padding,
     the centred eyebrow, and the 52px belt. The hero subtracts this so
     the composed group lands where the approved mock put it. */
  --logo-row-h: 104px;
  /* Base breathing interval for the fold composition. The buttons-to-logo
     gap uses it directly; the post-belt gap scales from it below. */
  --fold-gap: 144px;

  /* Third-party product marks in the harness belt. These are other companies'
     brand colors, not Nori accents — the ten-color palette governs our UI, it
     does not govern someone else's logo. This block is the ONLY place a hex
     literal may appear in this file; test-design-language.sh enforces that. */
  --brand-anthropic: #d97757;
  --brand-snowflake: #29b5e8;
}

/* ============ the drawing: rails + gutters ============ */
/* This sheet serves two layouts. The homepage is composed on `.frame` and runs
   full bleed to its rails; every other page that loads style.css is a centred
   column. The frame rules are therefore scoped under `.frame` — applying the
   homepage's geometry unscoped is what stripped the shared pages of their
   content column and left mobile text against the screen edge. */
.nav-inner, .hero-inner, .section-inner, .footer-inner, .footer-colophon {
  max-width: 1120px;
  margin: 0 auto;
  padding-left: 32px;
  padding-right: 32px;
}
/* .frame (design-tokens.css) draws the graph rule and the two rails.
   Everything inside shares one gutter so the eyebrow, the + marks, and the
   copy column all land on the same vertical. */
.frame .nav-inner, .frame .hero-inner, .frame .logos-section,
.frame .footer-inner, .frame .footer-colophon {
  max-width: none;
  margin: 0;
  padding-left: var(--gutter);
  padding-right: var(--gutter);
}
/* The + rail marks straddle the rails by design (.sect::after sits at
   right: -4.6px), which pushes the document ~4px wider than the viewport.
   `clip` contains that without creating a scroll container the way `hidden`
   would — the sticky nav depends on there not being one. */
.frame { overflow-x: clip; }
.sect > h2 { margin-bottom: 28px; }
/* No alternating fill. Every section sits on the same graph-rule canvas and is
   separated by its hairline and the + rail marks — a solid --base band painted
   over the drafting paper hides the one texture the page is drawn on. */

/* ============ nav ============ */
.nav {
  position: sticky; top: 0; z-index: 100;
  background: var(--deep);
  border-bottom: var(--hair);
}
.nav-inner { display: flex; align-items: center; gap: 24px; padding-top: 14px; padding-bottom: 14px; }
.nav-logo {
  display: inline-flex; align-items: center; gap: 8px;
  color: var(--fg); font-weight: 600; font-size: 16px; letter-spacing: -.01em;
}
.nav-logo:hover { text-decoration: none; color: var(--fg); }
.nav-links { margin-left: auto; display: flex; align-items: center; gap: 22px; font-size: 13.5px; }
.nav-links > a { color: var(--comment); }
.nav-links > a:hover { color: var(--text); text-decoration: none; }
/* Sign in serves existing customers, not acquisition, so it no longer competes
   with the fold's Free Trial button. Subdued to the same treatment as the
   other nav links, keeping the fold's bright green down to the wordmark and
   the CTA. Reverses the earlier "nav keeps every link at full strength"
   decision (Martin, 2026-08-11); padding is kept so nav height is unchanged. */
.nav-links > a.nav-cta {
  color: var(--comment); background: none;
  padding: 7px 14px; border-radius: var(--radius-btn); font-weight: 500;
}
.nav-links > a.nav-cta:hover { color: var(--text); background: none; text-decoration: none; }
.nav-dropdown { position: relative; }
.nav-dropdown::after {
  content: ""; position: absolute; top: 100%; left: 0; right: 0; height: 10px;
}
.nav-dropdown-toggle {
  background: none; border: none; padding: 0; cursor: pointer;
  color: var(--comment); font-family: var(--mono); font-size: 13.5px;
}
.nav-dropdown-toggle:hover { color: var(--text); }
.nav-dropdown-menu {
  position: absolute; top: calc(100% + 10px); left: -16px; min-width: 210px;
  background: var(--surface); border: var(--hair);
  display: none; flex-direction: column; padding: 6px 0;
  z-index: 101;
}
.nav-dropdown:hover .nav-dropdown-menu,
.nav-dropdown:focus-within .nav-dropdown-menu { display: flex; }
.nav-dropdown-menu a { color: var(--text); padding: 8px 16px; font-size: 13.5px; }
.nav-dropdown-menu a:hover { background: var(--overlay); color: var(--fg); text-decoration: none; }
.nav-toggle, .nav-burger { display: none; }  /* burger menu appears only on mobile */

/* ============ hero ============ */
/* Fold law: nav + hero fill 90–95vh so the next eyebrow visibly peeks. */
.hero { border-bottom: var(--hair); }
.hero-inner {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 520px);
  gap: 56px; align-items: center;
  padding-top: 64px; padding-bottom: 64px;
}
.hero-copy { min-width: 0; }
/* The 90-95vh fold is the homepage's law (pinned by test-homepage-v3.py). Left
   unscoped it stretched every shared hero to 92vh too, which is why it stays
   scoped to `.frame` rather than reaching the centred-column pages. */
.frame .hero-inner { min-height: calc(92vh - var(--nav-h)); }
.hero h1 { margin: 0 0 22px; text-align: left; }
.hero h1 .h1-hl { text-wrap: balance; }
/* The role pages (for-ops, for-security-leaders, for-finance, for-data) still
   run the v2 serif hero and share this sheet. The homepage opts out via
   .h1-stack and gives both phrases the local .h1-mono treatment below. */
.hero h1:not(.h1-stack) {
  display: flex; flex-direction: column; align-items: flex-start; gap: .14em;
  font-family: var(--serif); font-style: italic; font-weight: 420;
  font-size: clamp(32px, 3.6vw, 40px); line-height: 1.12; letter-spacing: -.012em;
  color: var(--fg);
}
.hero h1:not(.h1-stack) > span { display: block; white-space: nowrap; }
.hero-sub { font-size: 15.5px; color: var(--text); max-width: 52ch; margin: 0 0 18px; }
.hero-roles { font-size: 13px; color: var(--comment); margin: 0; }
.hero-roles a { color: var(--green); }

/* ---- v4 fold: one centred column, two actions ----
   The homepage hero dropped its proof pane, so the copy owns the full width
   and the two CTAs are the loudest thing above the fold. Scoped to
   .hero--centered so the four role pages keep the two-column v2 hero.

   .h1-mono is the mono display voice without the .h1-hl green chip, because
   this fold spends its one bright green on the Free Trial button. It lives
   here rather than in design-tokens.css: that file is SHA-pinned to the
   canonical v3.1 tokens by test-design-tokens.py and must stay byte-identical,
   so a local-only display variant cannot be added to it. If this voice earns a
   place in the library, it belongs upstream in the nori-design skill first. */
.hero--centered h1 .h1-mono {
  font-family: var(--mono); font-weight: 600; font-style: normal;
  letter-spacing: -.02em; color: var(--fg);
}
/* Both headline phrases sit inline on one line rather than stacked. */
.hero--centered h1.h1-stack--inline { display: block; }
.frame .hero-inner--centered {
  grid-template-columns: minmax(0, 1fr);
  justify-items: center;
}
.hero--centered .hero-copy { width: 100%; max-width: 780px; text-align: center; }
.hero--centered h1 {
  text-align: center;
  font-size: clamp(30px, 3.6vw, 44px); line-height: 1.16;
  margin: 0 0 20px;
}
.hero--centered .hero-sub {
  max-width: 60ch; margin: 0 auto 40px;
  color: var(--comment); text-wrap: balance;
}
.hero--centered .checkout-actions { max-width: none; margin-top: 0; }
/* No hairline between the fold and the logo row: the two read as one
   composition, the way the approved mock did. Role-page heroes keep theirs. */
.hero--centered { border-bottom: none; }
/* Sit the copy lower in the 92vh fold so the logo row that follows is close
   enough to belong to it, rather than stranded a third of a screen away. */
/* The approved mock treated the copy and the logo row as ONE centred group:
   164px above the headline, 144px between buttons and eyebrow, belt ending
   at ~82vh. Here they are two sibling sections, so the hero gives back the
   height the logo row needs and keeps its content centred in what is left.
   The composed group, not the hero alone, is what fills the fold now. */
.frame .hero-inner--centered {
  min-height: calc(76vh - var(--nav-h) - var(--logo-row-h));
  /* align-items:end puts every pixel of slack ABOVE the headline, which makes
     the gap below the buttons a fixed number instead of one that grows with
     the viewport. That is what lets it equal the gap under the belt. */
  align-items: end;
  padding-bottom: calc(var(--fold-gap) - 16px);   /* + .logos-section padding-top */
}
/* align-items:center keeps flex stretch from equalising the button heights,
   which is what lets the demo and CLI buttons sit visibly below the primary. */
.hero--centered .checkout-action-row {
  justify-content: center; align-items: center; gap: 12px;
}
.hero--centered .checkout-action-row > .btn-primary {
  flex: none; padding: 14px 32px; font-size: 15px; min-width: 168px;
}
.hero--centered .hero-demo { padding: 11px 22px; font-size: 15px; min-width: 140px; }
.hero--centered .onboarding-toggle { padding: 11px; }
.hero--centered .onboarding-launcher { margin-left: auto; margin-right: auto; }

@media (max-width: 860px) {
  /* Use a smaller base interval on mobile: at 144px the composition overran a
     568px-tall phone and nothing peeked. */
  :scope { --fold-gap: 88px; }
}
/* Short viewports get a tighter interval still. Keyed on height, not width,
   because what runs out on a 568px phone is vertical room. */
@media (max-height: 640px) {
  :scope { --fold-gap: 48px; }
}
@media (max-width: 860px) {
  .hero--centered .checkout-action-row { flex-direction: column; }
  .hero--centered .checkout-action-row > .btn-primary,
  .hero--centered .hero-demo { width: 100%; min-width: 0; }
}
.checkout-actions { width: 100%; max-width: 520px; }
.checkout-actions--hero { margin-top: 26px; }
.checkout-action-row { display: flex; align-items: stretch; gap: 8px; }
.checkout-action-row > .btn-primary { width: auto; flex: 1; justify-content: center; }
.onboarding-toggle { flex: none; justify-content: center; padding: 9px 11px; }
.onboarding-toggle[aria-expanded="true"] { color: var(--green); border-color: var(--subtle); }
.checkout-actions--pricing .onboarding-toggle { padding: 11px 12px; }
.terminal-icon { display: block; width: 18px; height: 18px; }
.onboarding-launcher {
  display: flex; align-items: stretch; flex: 1; min-width: 0;
  background: var(--base); border: var(--hair-nested);
  border-radius: var(--radius-btn); overflow: hidden; margin-top: 8px;
}
.onboarding-launcher[hidden] { display: none; }
.onboarding-prompt {
  flex: none; color: var(--green); font-size: 11px; padding: 9px 0 9px 10px;
}
.onboarding-launcher code {
  flex: 1; min-width: 0; padding: 8px; border: 0; border-radius: 0;
  background: transparent; color: var(--text); font-size: 10px; line-height: 1.45;
  overflow-x: auto; overflow-wrap: normal; white-space: nowrap;
}
.onboarding-copy {
  flex: none; align-self: stretch; border: 0; border-left: var(--hair-nested);
  border-radius: 0; padding: 8px 9px; font-size: 11px;
}

/* Keycaps and the nav caret are inline SVG, not glyphs. The self-hosted Plex
   Mono is a Latin-only subset, so U+23CE (return) and U+25BE (caret) fell
   through to the OS and rendered as tofu boxes on machines without them. */
.kbd-icon { width: 13px; height: 13px; display: block; }
kbd:has(.kbd-icon) { display: inline-flex; align-items: center; padding: 3px 6px; }
.nav-caret { width: 9px; height: 6px; margin-left: 5px; display: inline-block; vertical-align: middle; }

.hero-task-heading { display: flex; align-items: baseline; gap: 16px; margin-bottom: 10px; }
.hero-task-label { font-size: 13px; color: var(--comment); margin: 0; flex: 1; }
.hero-task-next {
  display: inline-flex; align-items: center; gap: 5px;
  background: none; border: var(--hair); border-radius: var(--radius-btn);
  color: var(--comment); font-family: var(--mono); font-size: 12px;
  padding: 4px 10px; cursor: pointer;
}
.hero-task-next:hover { color: var(--fg); border-color: var(--subtle); }
.hero-task-next svg { width: 14px; height: 14px; }
/* Fixed stage height so swapping the example never shifts the fold. */
.hero-animation-container #team-chat-animation { height: 520px; }
.hero-animation-stage { transition: opacity .28s linear; }
.hero-animation-stage.is-fading { opacity: 0; }
#team-chat-animation.slack-mock { border: var(--hair); background: var(--base); }

/* ============ belts ============ */
.logos-section { padding-top: 48px; padding-bottom: 56px; }
/* The homepage logo row is part of the v4 fold composition, so it sits
   close under the buttons and its eyebrow is centred over the belt. The
   'Run any agent' eyebrow below keeps its own left-aligned treatment. */
.hero--centered + .logos-section {
  padding-top: 16px;
  /* The post-belt interval was already 30% larger than the base, then Martin
     requested another 25% on 2026-08-12: 1.3 * 1.25 = 1.625. It remains
     derived from --fold-gap so the relationship scales at every breakpoint. */
  padding-bottom: calc(var(--fold-gap) * 1.625);
}
.hero--centered + .logos-section > .belt-eyebrow { text-align: center; }
.belt-eyebrow {
  font-size: var(--fs-label); font-weight: 500; letter-spacing: .09em;
  text-transform: uppercase;
}
.compat-heading { margin-top: 40px; }
/* The harness belt now follows Developer Automation as its own block, rather
   than sharing the customer-logo block. Its wrapper already supplies the
   vertical interval, so the heading needs no second top margin. */
.compatibility-section .compat-heading { margin-top: 0; }
/* Customer marks stay recognizable without competing with the hero. Their
   colour is deliberately subdued, with a small clarity lift on direct
   interaction so each linked logo still reads as interactive. */
/* One height for every mark. The assets carry the optical normalisation, so
   this stays a single rule — see docs.md before regenerating a logo. */
.belt-logo img {
  height: 28px; width: auto; display: block;
  filter: grayscale(.72) saturate(.32);
  opacity: .7;
  transition: filter .18s linear, opacity .18s linear;
}
.belt-logo:is(:hover, :focus-visible) img {
  filter: grayscale(.52) saturate(.5);
  opacity: .86;
}
a.belt-logo:hover { text-decoration: none; }
a.belt-logo:visited { color: var(--comment); }
/* Equal-width cards with the mark + label centered, so the conveyor reads as a
   catalog with a steady beat rather than a ragged queue. */
.belt-card { width: 208px; justify-content: center; color: var(--fg); padding-left: 14px; }
.belt-card .cp-logo { height: 13px; width: 13px; fill: currentColor; display: block; }
.belt-card-own { color: var(--comment); }
/* Harness marks carry color. Green stays reserved for the closing "your own
   agent" card so it keeps the pointer. */
.belt-ic.ic-blue      { color: var(--blue); }
.belt-ic.ic-cyan      { color: var(--cyan); }
.belt-ic.ic-magenta   { color: var(--magenta); }
.belt-ic.ic-yellow    { color: var(--yellow); }
.belt-ic.ic-anthropic { color: var(--brand-anthropic); }
.belt-ic.ic-snowflake { color: var(--brand-snowflake); }
.belt-ic.ic-white     { color: var(--fg); }
/* Cursor's mark is drawn for a light ground, so it gets its own dark tile. */
.belt-ic.ic-cursor    { color: var(--fg); background: var(--deep); border-color: var(--overlay); }
/* Antigravity ships a full-color mark, so the tile stays out of its way. */
.belt-ic.ic-antigravity { background: none; border-color: transparent; }
.belt-ic.ic-antigravity .cp-logo { height: 17px; width: 17px; }

.logos-footer { padding-top: 18px; max-width: 72ch; }
.logos-proof-line { color: var(--fg); font-size: 14px; margin: 0 0 6px; }
/* A number ships with the method behind it, or it is a fabricated metric. */
.logos-proof-method { color: var(--comment); font-size: 12.5px; line-height: 1.7; margin: 0 0 10px; }
.logos-story-link { font-size: 13px; }

/* ============ sections ============ */
/* The homepage uses the canonical `.sect` recipe from design-tokens.css. Every
   other page on this sheet uses `.section`, which is NOT a legacy alias — it is
   the live layout for the role pages, open-source and open-roles.
   `position: relative` is load-bearing: `.eyebrow` is absolutely positioned, so
   without it every section label re-anchors to <body> and stacks above the fold.
   The `max()` places the label on the content column's left edge at any width. */
.section { position: relative; border-top: var(--hair); padding: 72px 0; }
.section-alt { background: var(--base); }
.section .eyebrow { left: max(32px, calc((100% - 1120px) / 2 + 16px)); }
.section h2 {
  font-size: var(--fs-h1); font-weight: 600; letter-spacing: -.01em;
  margin: 0 0 28px; color: var(--fg);
}
.section-center { text-align: center; }

/* ============ developer automation ============ */
/* The lsgrid is an index of what is running. The automations are written out
   underneath it as prose, so nothing implies they are folders on disk. */
.lsgrid-cmd { margin: 0 0 10px; color: var(--text); }
.lsgrid .sum { margin-top: 12px; }
/* Columns mirror the real `nori cloud triggers` output: name, type
   (cron | webhook | reminder), what fires it, the skillset it runs under, and
   whether it is enabled. Deliberately no last-run column — invented run
   timestamps would be a fabricated metric. */
.trigger-table { width: 100%; border-collapse: collapse; font-size: 12.5px; min-width: 560px; }
.trigger-table th, .trigger-table td {
  text-align: left; font-weight: 400; padding: 5px 22px 5px 0; white-space: nowrap;
}
.trigger-table thead th {
  color: var(--comment); font-size: 11px; letter-spacing: .08em; text-transform: uppercase;
  border-bottom: 1px dashed var(--subtle); padding-bottom: 8px;
}
.trigger-table tbody tr:first-child th, .trigger-table tbody tr:first-child td { padding-top: 10px; }
.trigger-table tbody th { font-weight: 400; }
.trigger-table td { color: var(--comment); }
.trigger-table td.ok { color: var(--green); }

.automation-list {
  list-style: none; margin: 30px 0 0; padding: 0;
  display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr));
  border-top: var(--hair); border-left: var(--hair);
}
/* Three examples pinned side by side rather than reflowing by width, so the
   section reads as a trio and not a ragged grid. Stacks on narrow screens. */
.automation-list--trio { grid-template-columns: repeat(3, 1fr); }
@media (min-width: 901px) {
  /* These three panels share one 72px-quantized width and a 24px-quantized
     centring offset. Their outer edges and every third land halfway between
     the graph rules, so the panel geometry reads as a subdivision of paper. */
  :is(.lsgrid, .automation-list--trio, .concepts-grid) {
    --graph-panel-width: calc(round(down, calc(100% - 1px), 72px) + 1px);
    width: var(--graph-panel-width);
    margin-left: calc(
      round(
        nearest,
        calc((100% - var(--graph-panel-width)) / 2),
        24px
      )
    );
    margin-right: auto;
  }
  .automation-list--trio { grid-auto-rows: 240px; }
  .automation-list--trio .automation-item { border-bottom: 0; }
}
@media (max-width: 900px) {
  .automation-list--trio { grid-template-columns: minmax(0, 1fr); }
}
.automation-item { padding: 22px 24px 24px; border-right: var(--hair); border-bottom: var(--hair); }
.automation-item:hover { background: var(--base); }
.automation-item h3 {
  font-family: var(--serif); font-style: italic; font-weight: 420;
  font-size: 21px; letter-spacing: -.01em; color: var(--fg);
  margin: 0 0 10px; line-height: 1.25;
}
/* The slug ties each block back to its row in the listing above. */
.automation-slug {
  display: block; font-size: 11px; font-weight: 500; letter-spacing: .04em;
  color: var(--green); margin-bottom: 6px;
}
.automation-item p { font-size: 13px; color: var(--comment); line-height: 1.75; margin: 0; }

/* ============ concepts ============ */
.concepts-grid {
  display: grid; grid-template-columns: repeat(3, 1fr);
  border: var(--hair); border-right: none;
}
.concept-card { padding: 28px 30px 32px; border-right: var(--hair); background: var(--deep); }
.concept-card:hover { background: var(--surface); }
.concept-card h2 { font-size: var(--fs-h2); font-weight: 600; margin: 0 0 12px; color: var(--fg); }
.concept-card p { font-size: 13.5px; color: var(--comment); line-height: 1.7; margin: 0; }

/* ============ compare ============ */
/* .proof-table carries the structure; these are the homepage's column rules. */
.comparison-table { min-width: 640px; }
.comparison-table tbody th { color: var(--comment); font-size: 12px; white-space: nowrap; }
.comparison-table strong { color: var(--fg); font-weight: 600; display: block; margin: 6px 0 4px; }
.comparison-table td p { margin: 0; color: var(--comment); font-size: 12.5px; line-height: 1.6; }
.comparison-table td.compare-nori, .comparison-table th.compare-nori { background: var(--surface); }
.comparison-table thead th.compare-nori { color: var(--green); }
.visually-hidden {
  position: absolute; width: 1px; height: 1px; margin: -1px;
  clip: rect(0 0 0 0); overflow: hidden;
}

/* ============ pricing ============ */
.statement-text { margin: 0 auto 48px; }
.mention-lg { color: var(--green); }
.pricing-cards {
  display: grid; grid-template-columns: repeat(2, minmax(0, 320px));
  justify-content: center; gap: 20px; text-align: left;
}
.pricing-card { position: relative; border: var(--hair); background: var(--deep); padding: 28px; }
.pricing-card-premium { border-color: var(--subtle); }
/* The trial tag is quiet text, never a sticker. */
.pricing-trial-badge {
  position: absolute; top: -0.8em; left: 20px;
  background: var(--deep); padding: 0 8px;
  font-size: 11px; letter-spacing: .08em; text-transform: uppercase; color: var(--comment);
}
.pricing-card h3 { font-size: var(--fs-h2); font-weight: 600; color: var(--fg); margin: 0 0 14px; }
.pricing-card-price { margin-bottom: 12px; }
.pricing-amount { font-size: 32px; font-weight: 600; color: var(--fg); }
.pricing-amount-contact { font-size: 22px; }
/* nowrap so the qualifier never splits across lines the way "for 30 / days"
   did when the price tag became the trial offer. */
.pricing-interval { color: var(--comment); font-size: 13px; white-space: nowrap; }
.pricing-card-desc { font-size: 13px; color: var(--comment); line-height: 1.7; margin: 0 0 22px; }
.btn-lg { width: 100%; justify-content: center; padding: 11px 16px; }
a.btn { text-decoration: none; }
a.btn:hover { text-decoration: none; }
/* Buttons keep their own palette when visited — never the prose magenta (no purple-on-green). */
a.btn-primary:visited, a.btn-destructive:visited { color: var(--base); }
a.btn-secondary:visited { color: var(--text); }
a.btn-ghost:visited { color: var(--green); }

/* ============ subscribe modal ============ */
.subscribe-modal { position: fixed; inset: 0; z-index: 200; display: none; }
.subscribe-modal.active { display: block; }
.subscribe-modal-backdrop { position: absolute; inset: 0; background: rgba(14, 14, 14, .82); }
.subscribe-modal-content {
  position: relative; z-index: 1; max-width: 420px;
  margin: 10vh auto 0; background: var(--surface); border: var(--hair);
  padding: 28px;
}
.subscribe-modal-close {
  position: absolute; top: 10px; right: 10px;
  background: none; border: none; color: var(--comment);
  font-size: 20px; cursor: pointer; padding: 4px 8px; border-radius: var(--radius-tag);
}
.subscribe-modal-close:hover { color: var(--fg); }
.subscribe-modal-title { font-size: var(--fs-h2); margin: 0 0 6px; color: var(--fg); }
.subscribe-modal-plan-summary { font-size: 13px; color: var(--comment); margin: 0 0 20px; }
/* nowrap so the price qualifier never splits the way "$250 / month / after" did */
.subscribe-modal-plan-summary span { white-space: nowrap; }
.subscribe-modal-form { display: flex; flex-direction: column; }
.subscribe-modal-label { font-size: 12px; color: var(--comment); margin: 12px 0 6px; }
.subscribe-modal-input { width: 100%; }
.subscribe-modal-hint { font-size: 11.5px; color: var(--muted); margin: 6px 0 0; }
/* Slug feedback is a canonical callout: 9% tint, bright text, 3px spine.
   Empty state stays invisible so the form does not jump. */
.subscribe-modal-slug-status { font-size: 12px; margin: 8px 0 0; min-height: 1.4em; padding: 6px 10px; }
.subscribe-modal-slug-status:empty { border-left-color: transparent; background: none; padding: 0; min-height: 1.4em; }
.subscribe-modal-slug-status.available { background: rgba(66,190,101,.09); border-color: var(--green); color: var(--green-bright); }
.subscribe-modal-slug-status.taken { background: rgba(244,112,103,.09); border-color: var(--red); color: var(--red-bright); }
.subscribe-modal-slug-status.checking { background: none; border-color: transparent; color: var(--comment); padding-left: 0; }
.subscribe-modal-submit { margin-top: 24px; }
.subscribe-modal-submit:disabled { opacity: .5; cursor: not-allowed; }

/* ============ footer ============ */
.footer { border-top: var(--hair); }
.footer-inner {
  display: flex; align-items: center; gap: 20px; flex-wrap: wrap;
  padding-top: 32px; padding-bottom: 8px;
}
.footer-left { display: flex; align-items: center; gap: 14px; }
.footer-logo { display: inline-flex; align-items: center; gap: 7px; color: var(--fg); font-weight: 600; font-size: 14px; }
.footer-copy { color: var(--comment); font-size: 12.5px; }
.footer-links { margin-left: auto; display: flex; gap: 18px; font-size: 13px; }
.footer-links a { color: var(--comment); }
.footer-links a:hover { color: var(--text); }
.footer-colophon {
  padding-top: 10px; padding-bottom: 36px;
  display: flex; align-items: flex-end; justify-content: space-between; gap: 24px; flex-wrap: wrap;
}
/* $ exit is the EOF mark and the page's one opt-in personality moment. */
.footer-exit {
  background: none; border: none; padding: 0;
  color: var(--comment); font-size: 12.5px; font-family: var(--mono);
  text-align: left; line-height: 1.75;
}
/* The pointer and the hover lift are the affordance for the moment, so they
   belong to the homepage's <button>. On the other pages $ exit is a <p>, and
   an unscoped rule offered a click that does nothing. */
button.footer-exit { cursor: pointer; }
button.footer-exit:hover { color: var(--text); }
.footer-exit .ps { color: var(--green); }
.footer-moment-stage { margin-left: 10px; letter-spacing: .04em; white-space: pre; }
/* Palette colors only — the moment never introduces a new hue. */
.mo-fish { color: var(--blue); }
.mo-bone { color: var(--fg); }   /* cut faces: the - and + are bone */
.mo-sep  { color: var(--comment); }  /* the chop lines between the pieces */
.mo-rice { color: var(--text); }
.mo-nori { color: var(--g3); }
.mo-roll { color: var(--green); }
.mo-at   { color: var(--fg); }

/* ============ responsive ============ */
@media (max-width: 1279px) {
  .hero-inner { grid-template-columns: minmax(0, 1fr); gap: 40px; min-height: 0; }
}
@media (max-width: 900px) {
  :scope { --gutter: 20px; }
  .sect { padding-left: var(--gutter); padding-right: var(--gutter); }
  .hero-inner { grid-template-columns: minmax(0, 1fr); gap: 40px; padding-top: 48px; padding-bottom: 48px; }
  .concepts-grid { grid-template-columns: 1fr; border-right: var(--hair); }
  .concept-card { border-right: none; border-bottom: var(--hair); }
  .concept-card:last-child { border-bottom: none; }
  .pricing-cards { grid-template-columns: minmax(0, 420px); }
  .eyebrow { left: 16px; }
  .section .eyebrow { left: 20px; }
  /* The column goes full width on a phone but keeps its gutter; without this
     body copy on the shared pages runs flush into both screen edges. */
  .nav-inner, .hero-inner, .section-inner, .footer-inner, .footer-colophon {
    padding-left: 20px; padding-right: 20px;
  }
  .lsgrid-list .d { min-width: 0; display: block; margin-right: 0; }
}
@media (max-width: 768px) {
  .nav-logo .cursor { display: none; }
  /* Top bar collapses to a burger: logo + ☰ on one row, links drop into a panel when opened. */
  .nav-inner { flex-wrap: wrap; align-items: center; gap: 0; }
  .nav-logo { margin-right: auto; }
  .nav-burger { display: flex; flex-direction: column; gap: 4px; cursor: pointer; padding: 8px; margin: -8px -8px -8px 0; }
  .nav-burger span { display: block; width: 22px; height: 2px; background: var(--comment); transition: background var(--t-hover); }
  .nav-burger:hover span { background: var(--text); }
  .nav-links { display: none; margin-left: 0; flex-basis: 100%; width: 100%; flex-direction: column; align-items: stretch; gap: 0; padding-top: 8px; }
  .nav-toggle:checked ~ .nav-links { display: flex; }
  .nav-links > a { padding: 11px 2px; font-size: 14px; border-top: var(--hair); }
  .nav-links > a.nav-cta { background: none; color: var(--comment); padding: 11px 2px; border-radius: 0; font-weight: 500; }
  .nav-links > a.nav-cta:hover { background: none; color: var(--text); }
  /* The Solutions hover menu flattens into the panel (hover doesn't work on touch). */
  .nav-dropdown { position: static; width: 100%; border-top: var(--hair); }
  .nav-dropdown::after { display: none; }
  .nav-dropdown-toggle { width: 100%; text-align: left; padding: 11px 2px; font-size: 14px; }
  .nav-dropdown-menu { display: flex; position: static; top: auto; left: auto; min-width: 0; border: none; background: none; padding: 0 0 6px; }
  .nav-dropdown-menu a { padding: 8px 2px 8px 16px; font-size: 13.5px; }
  .hero-task-heading { flex-wrap: wrap; }
  .onboarding-launcher { width: 100%; }
  .comparison-table { font-size: 12.5px; }
  .footer-inner { flex-direction: column; align-items: flex-start; }
  .footer-links { margin-left: 0; display: grid; grid-template-columns: 1fr 1fr; gap: 12px 20px; width: 100%; }
  /* The EOF mark stays on the phone — it is the page's last line, not chrome. */
  .footer-colophon { padding-bottom: 28px; }
}

/* Book-a-demo: the Google appointment-scheduler page embedded inline inside a
   thin hairline Nori frame (.term). The picker is Google's and not restylable,
   so the wrapper stays minimal; a new-tab fallback link is always present. */

/* ============================================================
   SITE THEME OVERRIDES  --  keep byte-identical with the copy in
   the sibling stylesheet (style.css <-> blog.css). Every page on
   this site loads exactly one of the two, and together they cover
   all 84 pages that load design-tokens.css; test-design-language.sh
   fails if the two blocks drift apart.

   These three values align the shared pages with the redesigned
   homepage, so a visitor moving from "/" to any other page does not
   see the ground, the reading face and the wordmark all change under
   them (Martin, 2026-09-08).

   They live here and not in design-tokens.css on purpose. That file
   is a copy of the canonical v3.1 token sheet owned by the
   nori-design skill -- "copy this file into the site, do not
   hotlink" -- and test-design-tokens.py pins its SHA-256 precisely
   so a site cannot fork the design system by editing its local
   copy. Overriding downstream of it is the supported way to do this;
   editing it in place would have meant bumping that hash and
   silently forking the shared tokens for every repo that vendors
   them. If these values should become the design system's, they
   belong upstream in the skill, and then this block goes away.
   ============================================================ */
:scope {
  /* re-grounded on the homepage canvas; was the v3.1 ramp's own deep step */
  --deep: #121212;
  /* General Sans is the homepage's running-text face. Mono still leads
     on nav, labels, meta and code, exactly as the design law says --
     this is the body voice only. fonts.css explains why it arrives
     from Fontshare rather than being self-hosted. */
  --sans: 'General Sans', ui-sans-serif, system-ui, -apple-system, sans-serif;
}
body { font-family: var(--sans); }
/* The nav mark is "nori" with no trailing prompt caret: the homepage
   dropped it in the redesign and two marks cannot coexist in one site.
   Hidden rather than deleted from 84 files by hand, so restoring it is
   this one rule. */
.wordmark .prompt,
.nav-logo .prompt { display: none; }
/* ==================== end site theme overrides ==================== */

}
