{
  "kata": "0.1",
  "system": {
    "name": "Hanabira",
    "compiledFrom": [
      {
        "kind": "tokens",
        "ref": "hana/apps/landing/src/styles/global.css",
        "method": "parsed",
        "note": "Two token blocks from two eras: the original palette, then a 'Leaf family design system, Hana edition' block appended below it."
      },
      {
        "kind": "components",
        "ref": "hana/apps/landing/src/components/*.astro",
        "method": "parsed"
      },
      {
        "kind": "code",
        "ref": "hana/apps/landing/src/pages/index.astro",
        "method": "parsed"
      },
      {
        "kind": "url",
        "ref": "http://localhost:4321 (astro dev)",
        "method": "rendered inspection at three widths"
      },
      {
        "kind": "code",
        "ref": "hana/apps/example/src/styles/index.css",
        "method": "parsed",
        "note": "The app surface. It is Vite starter boilerplate, recorded as found."
      }
    ],
    "compiledAt": "2026-08-03",
    "widths": [
      1440,
      900,
      390
    ],
    "complete": true,
    "note": "Compiled from shipped source plus a live run of the landing. Nothing was written down before it was built, so the open list is dominated by intent questions no scrape can answer. No overflow at any inspected width."
  },
  "surfaces": {
    "marketing": {
      "description": "The landing at hanabira.dev. Dark only — no light theme exists.",
      "appliesTo": [
        "hanabira.dev/",
        "hana/apps/landing/**"
      ],
      "roles": {
        "page": {
          "value": "#0C0C0D",
          "confidence": "stated",
          "source": "--bg-primary"
        },
        "navBg": {
          "value": "#000000",
          "confidence": "stated",
          "source": "--nav-bg"
        },
        "footerBg": {
          "value": "#000000",
          "confidence": "stated",
          "source": "Footer.astro"
        },
        "tile": {
          "value": "#0E0E10",
          "confidence": "stated",
          "source": "--tile-bg"
        },
        "card": {
          "value": "#131316",
          "confidence": "stated",
          "source": "Card.astro, raw hex in component"
        },
        "textPrimary": {
          "value": "#8A898C",
          "confidence": "stated",
          "source": "--text-primary, applied to * globally",
          "note": "5.62:1 on page. Passes AA for body. This mid-grey is also the base colour of every heading, because the global * rule paints them. See unspecified/text-hierarchy-inversion."
        },
        "textSecondary": {
          "value": "#C7CDE1",
          "confidence": "stated",
          "source": "--text-secondary",
          "note": "12.34:1. The 'secondary' colour is brighter and higher-contrast than 'primary'. The names run backwards relative to their jobs."
        },
        "cardTitle": {
          "value": "#FFFFFF",
          "confidence": "stated",
          "source": "--card-title"
        },
        "border": {
          "value": "#222223",
          "confidence": "stated",
          "source": "--border-primary"
        },
        "line": {
          "value": "rgba(199, 205, 225, .1)",
          "confidence": "stated",
          "source": "--line, Hana-edition block",
          "note": "Second hairline token from the later era. Tilebeds use this; older components use --border-primary. Two hairlines, one job."
        },
        "accent": {
          "value": "#8B9CE0",
          "confidence": "stated",
          "source": "Michael, review 2026-08-03, resolving conflict two-accents",
          "note": "7.38:1 on page, 7.00:1 on card. The --hana token is the accent. #5E79C7 remains recorded below as legacy."
        },
        "petal": {
          "value": "#C391D9",
          "confidence": "stated",
          "source": "--petal",
          "role": "the kanji slot in eyebrows, gradient mid-stop"
        },
        "eyebrowPrefix": {
          "value": "#4A4A52",
          "confidence": "stated",
          "source": ".eyebrow::before",
          "fails": "2.23:1 on page. Below AA at any size. If the // prefix is content, it fails; if decorative, it should be marked aria-hidden and is not."
        },
        "footerHairline": {
          "value": "#272D41",
          "confidence": "stated",
          "source": "Footer.astro box-shadow 0 -1px",
          "conflict": "hairline-value",
          "note": "A third line colour, drawn as a shadow rather than a border."
        },
        "accentLegacy": {
          "value": "#5E79C7",
          "confidence": "stated",
          "source": "--accent, original era",
          "note": "Superseded. Live in the header SVG stroke; migrate to #8B9CE0."
        }
      }
    },
    "app": {
      "description": "The example application shipped in the monorepo.",
      "appliesTo": [
        "hana/apps/example/**"
      ],
      "roles": {
        "page": {
          "value": "#242424",
          "confidence": "stated",
          "source": "index.css",
          "note": "Vite starter default, not a decision."
        },
        "text": {
          "value": "rgba(255,255,255,.87)",
          "confidence": "stated",
          "note": "Same."
        },
        "progress": {
          "value": "green",
          "confidence": "stated",
          "note": "The nprogress bar ships with the CSS keyword green. Nothing about it belongs to any palette."
        }
      },
      "note": "This surface is scaffold boilerplate, recorded as found. It shares nothing with the landing: different font (Inter), different background, keyword colours. See unspecified/app-surface-exists."
    },
    "docs": {
      "description": "VitePress documentation using @leafphp/docs-theme. Present in the repo, and NOT a source for any other surface.",
      "appliesTo": [
        "hana/apps/docs/**"
      ],
      "roles": {},
      "note": "Deliberately empty. This theme belongs to the Leaf docs, not to Hanabira. Harvesting from it would import a third system's values."
    }
  },
  "type": {
    "pairing": {
      "display": "Bricolage Grotesque",
      "text": "Bricolage Grotesque",
      "mono": "Berkeley Mono (self-hosted woff)",
      "confidence": "stated",
      "note": "One family for display and body at weight 800/400, matching the Leaf family pattern. Berkeley Mono is declared at font-weight 500 while the file is named Regular — quirk recorded, not resolved."
    },
    "scale": {
      "h1": {
        "value": "96px / 800",
        "confidence": "stated",
        "source": "global.css",
        "conflict": "hero-display-size"
      },
      "heroTitleShipped": {
        "value": "clamp(52px, 7vw, 92px)",
        "confidence": "stated",
        "source": "index.astro .hero-title",
        "measured": {
          "390": "52px",
          "900": "63px",
          "1440": "92px"
        }
      },
      "h2": {
        "value": "82px / 800",
        "confidence": "stated"
      },
      "h3": {
        "value": "52px / 800",
        "confidence": "stated"
      },
      "sectionTitleShipped": {
        "value": "clamp(34px, 4vw, 52px) — and a second variant clamp(34px, 4vw, 56px) in the same file",
        "confidence": "stated",
        "note": "Two clamps for the same role, 52 vs 56 max. Drift, not intent, most likely — but that is a guess and it is not encoded."
      },
      "heroSubtext": {
        "base": "24px",
        "below738": "18px",
        "confidence": "stated",
        "measured": {
          "390": "18px"
        }
      },
      "body": {
        "value": "16px",
        "confidence": "stated"
      }
    }
  },
  "space": {
    "scale": null,
    "enforce": false,
    "confidence": "measured",
    "note": "No scale exists, and per review 2026-08-03 that is intentional — spacing is reviewed by eye. Shipped paddings sampled: 10, 12, 16, 20, 24, 34, 40, 44, 48, 50, 60, 70, 80, 85, 100, 140. enforce stays false."
  },
  "radius": {
    "components": 0,
    "navPill": 999,
    "decorative": "50% circles, one organic petal shape (100% 4% 100% 100%)",
    "confidence": "stated",
    "note": "Squared components with a pill nav action — the Leaf family shape grammar. One fossil: global.css states pre { border-radius: 14px } and the Hana-edition block below it overrides to 0. See conflict corner-radius-era."
  },
  "composition": {
    "breakpoints": [
      {
        "name": "global-type",
        "max": 738,
        "intent": "h1 and h2 drop to 48px, hero subtext to 18px",
        "confidence": "stated",
        "source": "global.css"
      },
      {
        "name": "cards-and-footer",
        "max": 720,
        "intent": "card and footer padding collapses",
        "confidence": "stated",
        "source": "Card.astro, FeedbackCard.astro, Footer.astro"
      },
      {
        "name": "nav-switch",
        "min": "50em (800px)",
        "intent": "header switches from disclosure menu to inline nav, via matchMedia in script",
        "confidence": "stated",
        "source": "Header.astro"
      },
      {
        "name": "note",
        "intent": "Three different mobile thresholds — 720, 738, 800 — govern one page. Whether this is one breakpoint with drift or three decisions is unanswerable from source. See unspecified/breakpoint-consolidation."
      }
    ],
    "grid": [
      {
        "id": "hairline-tile-grid",
        "rule": "Grids of tiles use a 1px gap over a line-coloured bed, not per-tile borders.",
        "why": "Shared hairlines read as one drawn grid. This is the Leaf family convention, stated here in the Hana-edition block.",
        "check": "Tile containers use gap: 1px with background set to --line.",
        "checkable": "auto",
        "source": ".tilebed, four instances live",
        "confidence": "stated"
      },
      {
        "source": "Leaf family invariant, applies to Hanabira per Michael, review 2026-08-03",
        "confidence": "stated",
        "id": "shared-tracks",
        "rule": "Stacked grids share column tracks and gaps. A section heading that sits above a list must use the same track definition as the list.",
        "check": "Compare grid-template-columns and gap of each heading block against the content grid beneath it.",
        "checkable": "auto"
      },
      {
        "source": "Leaf family invariant, applies to Hanabira per Michael, review 2026-08-03",
        "confidence": "stated",
        "id": "paired-panes-share-rows",
        "rule": "Side-by-side comparison panes share row tracks.",
        "check": "Paired panes use subgrid or equivalent equal-height behaviour.",
        "checkable": "model"
      },
      {
        "source": "Leaf family invariant, applies to Hanabira per Michael, review 2026-08-03",
        "confidence": "stated",
        "id": "stack-on-content",
        "rule": "A grid collapses at the width its content stops fitting, not at the shared breakpoint.",
        "check": "manual",
        "checkable": "manual"
      }
    ],
    "alignment": [
      {
        "source": "Leaf family invariant, applies to Hanabira per Michael, review 2026-08-03",
        "confidence": "stated",
        "id": "balanced-display-lines",
        "rule": "Display type balances, body ledes balance, no line ends with a one- or two-word orphan.",
        "check": "text-wrap balance on display and lede, plus a rendered orphan check.",
        "checkable": "model"
      },
      {
        "source": "Leaf family invariant, applies to Hanabira per Michael, review 2026-08-03",
        "confidence": "stated",
        "id": "numeric-columns",
        "rule": "Stacked figure-and-label rows reserve a fixed width for the figure.",
        "check": "Figures in repeated rows set min-width.",
        "checkable": "auto"
      }
    ],
    "alignmentNote": "Alignment invariants inherited from the Leaf family, confirmed by Michael, review 2026-08-03. Nothing composition-level is stated in this repo itself.",
    "motion": [
      {
        "id": "petals-respect-reduced-motion",
        "rule": "The falling-petal hero animation honours prefers-reduced-motion: reduce.",
        "check": "HeroBG animations disabled inside the reduce media block.",
        "checkable": "auto",
        "source": "HeroBG.astro:98",
        "confidence": "stated",
        "note": "Stated for the hero only. No other animated element declares a reduce path, and no global rule exists."
      },
      {
        "source": "Leaf family invariant, applies to Hanabira per Michael, review 2026-08-03",
        "confidence": "stated",
        "id": "buttons-change-colour-only",
        "rule": "Buttons transition colour only. They do not lift, scale or translate.",
        "check": "No transform on :hover for button elements.",
        "checkable": "auto"
      },
      {
        "id": "all-motion-respects-reduce",
        "rule": "Every animation and transition honours prefers-reduced-motion, not just the hero petals.",
        "check": "No animation or transition longer than 1ms inside a reduce block.",
        "checkable": "auto",
        "source": "Michael, review 2026-08-03, resolving reduced-motion-scope",
        "confidence": "stated",
        "note": "Known finding: no element other than HeroBG currently declares a reduce path."
      }
    ]
  },
  "patterns": {
    "eyebrow": {
      "use": "Mono uppercase label above a section title. // prefix in muted ink, label text in hana blue, optional kanji slot in petal.",
      "spec": {
        "family": "Berkeley Mono",
        "size": "12px",
        "tracking": "0.2em",
        "transform": "uppercase",
        "prefix": "// in #4A4A52",
        "text": "accent",
        "kanji": "Bricolage 600, petal, 0.08em"
      },
      "confidence": "stated",
      "source": ".eyebrow, six instances live",
      "note": "Same grammar as Leaf's eyebrow with the muted/accent split in the same places. The kanji slot is Hanabira's own addition."
    },
    "gradientDisplay": {
      "use": "Display type filled with the three-stop petal gradient (#8296B3 to #C391D9 to #E5E5F5). The hero h1, four section h3s and the community h2 all carry it.",
      "spec": "linear-gradient(140deg) with bg-clip-text",
      "confidence": "stated",
      "source": ".gradient-text, six instances live",
      "note": "Confirmed as the norm by Michael, review 2026-08-03, resolving the Leaf-side gradient-policy conflict: Leaf and Hanabira are the frontline runners and the gradient is theirs alone.",
      "neverUse": [
        "any product outside Leaf and Hanabira — the gradient is frontline brand identity and does not transfer"
      ],
      "rule": "Every display heading carries the gradient. A heading rendering in the grey base colour is a bug, not a variant — the grey is the pre-paint fallback.",
      "check": "Every h1/h2/h3 acting as a section or hero title carries .gradient-text.",
      "checkable": "auto"
    },
    "cornerMarker": {
      "use": "5px square markers in accent blue on the corners of a bordered panel. All four corners, offset 3px outside.",
      "spec": {
        "size": "5px",
        "shape": "square",
        "colour": "accent",
        "corners": 4
      },
      "confidence": "stated",
      "source": ".marker.tl/.tr/.bl/.br, eight instances live (two panels)"
    },
    "linkCard": {
      "use": "Feature card with a blurred colour orb behind it, colour passed per-card as a raw hex prop.",
      "spec": {
        "bg": "#131316",
        "radius": 0,
        "orbColours": "per-instance: #625454, #DB1010, #591040, #594410 and others"
      },
      "confidence": "stated",
      "source": "Card.astro + index.astro props",
      "note": "The orb colours are content-level hexes that belong to no token. Whether that is intentional (each card owns a hue) or debt is not answerable from source. See unspecified/card-orb-colours."
    },
    "terminalCommand": {
      "use": "An install command in Berkeley Mono inside a squared pre, click-to-copy (cursor: copy).",
      "confidence": "stated",
      "source": "global.css pre rules"
    }
  },
  "prohibitions": [
    {
      "id": "no-rounded-components",
      "rule": "Components are squared. Hairline grids, mono eyebrows, squared corners is the stated intent line.",
      "source": "stated",
      "evidence": "global.css comment in the Hana-edition block, plus the pre radius override to 0 and radius 0 on cards",
      "checkable": "auto",
      "note": "One pill exception: the nav CTA at 999px, matching the Leaf family."
    },
    {
      "id": "no-light-theme",
      "rule": "The landing is dark only.",
      "source": "stated",
      "evidence": "no light values, no prefers-color-scheme handling, no theme toggle anywhere in the landing; confirmed in review 2026-08-03",
      "checkable": "auto"
    },
    {
      "id": "no-window-chrome",
      "rule": "No fake window chrome. No traffic lights, no title bars, no browser frames around anything that is not a browser.",
      "source": "stated",
      "evidence": "Michael, review 2026-08-03",
      "checkable": "auto"
    },
    {
      "id": "no-emoji-icons",
      "rule": "Icons are drawn, never typed. No emoji anywhere in the interface.",
      "source": "stated",
      "evidence": "Michael, review 2026-08-03",
      "checkable": "auto"
    },
    {
      "id": "no-sparkle",
      "rule": "No four-point sparkle in any form.",
      "source": "stated",
      "evidence": "Michael, review 2026-08-03",
      "checkable": "auto"
    }
  ],
  "conflicts": [
    {
      "id": "hero-display-size",
      "claim": {
        "value": "h1: 96px fixed",
        "source": "global.css"
      },
      "observed": {
        "value": ".hero-title: clamp(52px, 7vw, 92px), which wins in the cascade and renders 92px at 1440",
        "source": "index.astro:313, measured live"
      },
      "resolution": null,
      "blocking": false,
      "note": "Both are stated. The global rule is dead code on the only h1 in the app, but a new page adding an h1 would get 96px."
    },
    {
      "id": "two-accents",
      "claim": {
        "value": "#5E79C7 (--accent, original block; also hardcoded as an SVG stroke in Header.astro)",
        "source": "global.css, Header.astro"
      },
      "observed": {
        "value": "#8B9CE0 (--hana, Hana-edition block; eyebrows and markers)",
        "source": "global.css"
      },
      "resolution": "#8B9CE0. Michael, review 2026-08-03. --accent #5E79C7 is legacy and should migrate, including the hardcoded header SVG stroke.",
      "blocking": false,
      "note": "Two stated blues from two eras, both live on the page. Which is THE accent decides every future component. A compiler must not choose."
    },
    {
      "id": "corner-radius-era",
      "claim": {
        "value": "pre { border-radius: 14px }",
        "source": "global.css:106, original block"
      },
      "observed": {
        "value": "pre { border-radius: 0 } plus the squared-corners intent comment",
        "source": "global.css:169, Hana-edition block"
      },
      "resolution": null,
      "blocking": false,
      "note": "The cascade resolves this one — 0 wins — but the fossil documents a redesign mid-file, and the human should confirm the squared era is the settled one before the 14px block is deleted."
    },
    {
      "id": "hairline-value",
      "claim": {
        "value": "#222223 (--border-primary) and rgba(199,205,225,.1) (--line)",
        "source": "global.css, both stated"
      },
      "observed": {
        "value": "#272D41 drawn as a box-shadow on the footer",
        "source": "Footer.astro:22"
      },
      "resolution": null,
      "blocking": false,
      "note": "Three line colours for one job, one of them drawn with the wrong tool. No stated rule picks between them."
    }
  ],
  "unspecified": [
    {
      "id": "text-hierarchy-inversion",
      "question": "textSecondary (#C7CDE1, 12.3:1) is brighter than textPrimary (#8A898C, 5.6:1), and headings inherit the grey primary via the global * rule while card titles get white from their own token. Is the naming intentional, and is grey-base-headings a decision or an accident of the reset?",
      "assumed": "Shipped as stated.",
      "raisedBy": "compile",
      "severity": "high",
      "status": "closed",
      "closedBy": "Michael, review 2026-08-03: headings are not grey — the gradient is applied to display type by design. The grey base is the pre-paint fallback. The naming question is split out below."
    },
    {
      "id": "spacing-scale",
      "question": "Sixteen distinct padding values with no repeating basis. Is there an intended scale?",
      "assumed": "None. Values recorded as found.",
      "raisedBy": "compile",
      "severity": "high",
      "status": "closed",
      "closedBy": "Michael, review 2026-08-03: no scale exists on purpose. Spacing is reviewed by eye. enforce stays false; the sixteen shipped values stand as found."
    },
    {
      "id": "reduced-motion-scope",
      "question": "The hero petals honour prefers-reduced-motion; nothing else declares a reduce path. Is reduced-motion a system requirement or a one-off?",
      "assumed": "One-off.",
      "raisedBy": "compile",
      "severity": "high",
      "status": "closed",
      "closedBy": "Michael, review 2026-08-03: a system requirement. Encoded as all-motion-respects-reduce; non-hero animations are now a known finding."
    },
    {
      "id": "family-invariants",
      "question": "The Hana-edition block imports Leaf's visual grammar (tilebeds, markers, eyebrows, squared corners). Do Leaf's composition invariants — shared grid tracks, balanced display lines, buttons-never-move — also apply here by inheritance?",
      "assumed": "Not applied. Nothing composition-level is stated in this repo.",
      "raisedBy": "compile",
      "severity": "medium",
      "status": "closed",
      "closedBy": "Michael, review 2026-08-03: they apply. Injected into composition."
    },
    {
      "id": "breakpoint-consolidation",
      "question": "720, 738 and 800 all govern mobile behaviour on one page. One breakpoint with drift, or three decisions?",
      "assumed": "Drift.",
      "raisedBy": "compile",
      "severity": "medium",
      "status": "open"
    },
    {
      "id": "app-surface-exists",
      "question": "The example app is unstyled Vite boilerplate. Does a designed app surface exist anywhere, or is the landing the only designed surface?",
      "assumed": "Landing only.",
      "raisedBy": "compile",
      "severity": "medium",
      "status": "open"
    },
    {
      "id": "eyebrow-prefix-contrast",
      "question": "The // prefix sits at 2.23:1. If it is content it fails AA; if it is decorative it needs aria-hidden, which it lacks. Which is it?",
      "assumed": "Decorative, unmarked.",
      "raisedBy": "compile",
      "severity": "medium",
      "status": "open"
    },
    {
      "id": "card-orb-colours",
      "question": "Card orbs take raw hexes per instance (#DB1010, #591040, ...). Intentional per-card hues, or token debt?",
      "assumed": "Intentional content, off-token.",
      "raisedBy": "compile",
      "severity": "low",
      "status": "open"
    },
    {
      "id": "section-title-clamp-variants",
      "question": "clamp(34px,4vw,52px) and clamp(34px,4vw,56px) both style section titles in the same file. Which is canonical?",
      "assumed": "Drift.",
      "raisedBy": "compile",
      "severity": "low",
      "status": "open"
    },
    {
      "id": "text-role-naming",
      "question": "textSecondary is brighter and higher-contrast than textPrimary. The hierarchy is intentional in effect, but the names run backwards. Rename, or keep?",
      "assumed": "Kept as shipped.",
      "raisedBy": "review",
      "severity": "low",
      "status": "open"
    }
  ]
}
