{
  "$schema": "https://simt.space/cosmos-design/rules.schema.json",
  "$description": "Cosmos 2.4.0 rules for the Web app part: the common foundations and this part's own sections. Every part is in rules.json.",
  "version": "2.4.0",
  "updated": "2026-10-03",
  "status": "Normative specification",
  "platform": { "id": "web-app", "label": "Web app" },
  "inheritance": "Platform rules are additive to common; product safety, privacy and accessibility take precedence.",
  "normativeLanguage": {
    "must": "Required for conformance.",
    "should": "Expected unless an explicit evidence-backed exception is recorded.",
    "may": "Optional within the common constraints."
  },
  "ruleCount": 43,
  "sections": [
    {
      "id": "identity",
      "title": "Identity & authority",
      "summary": "A useful spatial system, with room for imagination.",
      "platform": "common",
      "url": "https://simt.space/cosmos-design/common#identity",
      "rules": [
        {
          "id": "C01",
          "title": "Task before spectacle",
          "level": "must",
          "requirement": "Put the primary object, current state and next action in the first useful viewport. A decorative motif may frame them but cannot displace them. Use literal operational copy even when the visual language is celestial.",
          "acceptance": "In grayscale, a first-time reader can identify the task, state and next step. Removing all ornament leaves a complete interface.",
          "url": "https://simt.space/cosmos-design/common#c01"
        },
        {
          "id": "C02",
          "title": "Shared core, four adapters",
          "level": "must",
          "requirement": "Apply these common rules and the relevant platform part together. Product safety, privacy and accessibility requirements take precedence. Older prototypes and repository guides are migration evidence where they disagree with v2.",
          "acceptance": "Each implementation brief names version 2.4.0, platform, applicable rule IDs, owner and any explicit exception with reason, evidence and review date.",
          "url": "https://simt.space/cosmos-design/common#c02"
        },
        {
          "id": "C03",
          "title": "Original composition",
          "level": "must",
          "requirement": "Build visual identity from the focus aperture, context spine and horizon ribbon. An aperture frames one meaningful object and is drawn as a quasar: a solid core in the object's channel, a corona halo and, where space allows, an accretion ring. A spine connects current context to the next step; a ribbon orders actual time or distance. Compose with continuous fields and aligned rows before adding cards.",
          "acceptance": "Every motif names the information it carries. One quasar aperture per screen marks the focal object. Cards contain individual records; no nested record cards or identical boxes around every page section.",
          "url": "https://simt.space/cosmos-design/common#c03"
        }
      ]
    },
    {
      "id": "palette",
      "title": "Color with a job",
      "summary": "The original Deep Space colors are preserved exactly.",
      "platform": "common",
      "url": "https://simt.space/cosmos-design/common#palette",
      "table": {
        "caption": "Deep Space token registry",
        "columns": ["Token", "sRGB", "oklch (web)", "Role"],
        "rows": [
          ["void", "#120A14", "oklch(16.10% 0.0242 319.45deg)", "Page and immersive field"],
          ["void-edge", "#1F1126", "oklch(20.77% 0.0447 313.68deg)", "Depth at the edge of the field"],
          ["hull", "#1D1220", "oklch(20.34% 0.0317 318.9deg)", "Standard opaque surface"],
          ["hull-raised", "#2A1830", "oklch(24.45% 0.0506 317.34deg)", "Raised or selected surface"],
          ["hull-highest", "#352040", "oklch(28.55% 0.0626 313.19deg)", "Highest temporary surface"],
          ["ember", "#FF8C42", "oklch(75.36% 0.1637 50.4deg)", "Primary agency: create, continue, commit"],
          ["ember-soft", "#FFB27C", "oklch(82.54% 0.1139 55.48deg)", "Supporting warm emphasis"],
          ["rose", "#FF7E8A", "oklch(74.38% 0.1570 15.89deg)", "Social participation and attention"],
          ["violet", "#C9A0FF", "oklch(77.84% 0.1380 303.2deg)", "Identity, roles and transformation"],
          ["gold", "#FFC766", "oklch(86.11% 0.1307 79.28deg)", "Focus, time, precision and value"],
          ["cyan", "#00E5FF", "oklch(84.42% 0.1457 209.29deg)", "Live, connected and located"],
          ["moss", "#83B692", "oklch(73.03% 0.0750 153.51deg)", "Outdoor and natural categories"],
          ["danger", "#FF6978", "oklch(71.17% 0.1827 17.02deg)", "Destructive action and failure"],
          ["success", "#71D5A4", "oklch(79.88% 0.1186 160.71deg)", "Confirmed completion"],
          ["petrol", "#102C2D", "oklch(27.21% 0.0338 198.5deg)", "Map ground"],
          ["water", "#123D42", "oklch(33.30% 0.0470 205.97deg)", "Map water"],
          ["ink", "#FFF8F2", "oklch(98.29% 0.0110 63.36deg)", "Primary text on Deep Space"],
          ["muted", "#BBAEBB", "oklch(76.57% 0.0233 325.8deg)", "Supporting text"],
          ["faint", "#9A8B9A", "oklch(65.48% 0.0280 325.89deg)", "Secondary metadata; check actual surface"],
          ["dim", "#90839A", "oklch(62.93% 0.0371 310.51deg)", "Inactive ornament; not essential text"],
          ["boundary", "#9A8B9A", "oklch(65.48% 0.0280 325.89deg)", "Essential control outlines on dark surfaces"]
        ]
      },
      "rules": [
        {
          "id": "C04",
          "title": "Stable semantic channels",
          "level": "must",
          "requirement": "Use Ember for primary agency, Rose for social attention, Violet for identity, Gold for focus/time/value, Cyan for live/location state and Moss for nature. Danger and Success are separate status channels. Limit competing large accents to one dominant and two supporting channels; categorized data may use the spectrum with labels.",
          "acceptance": "Tokens resolve to the anchors below. A hue never supplies the only meaning. Category Moss cannot imply a successful operation; Rose cannot imply an error.",
          "url": "https://simt.space/cosmos-design/common#c04"
        },
        {
          "id": "C05",
          "title": "Contrast is composited",
          "level": "must",
          "requirement": "Require 4.5:1 normal text, 3:1 large text and 3:1 essential control boundaries, focus and graphical objects against adjacent colors. Use boundary for necessary input outlines; line is decorative only. Check every gradient stop, translucent surface and hover/disabled distinction.",
          "acceptance": "Measure the final composited pairs in each theme. The measurements are published once at contrast-pairs.json; fetch that document when introducing a colour, pairing a translucent or gradient surface or checking a theme, and do not expect a token payload to carry them. Document any inactive-control exception. Faint is supporting text only on a passing surface; Dim is never needed to complete a task.",
          "url": "https://simt.space/cosmos-design/common#c05"
        },
        {
          "id": "C06",
          "title": "Daylight, red and ambient",
          "level": "must",
          "requirement": "Offer Daylight Nebula where supported. Dark remains the signature; a persisted explicit choice wins over the system preference, and with no choice the system preference is followed. Astronomy red is user-selected for instruments, uses only red luminance and retains text contrast. Watch ambient may use pure black for OLED efficiency. Theme adapters preserve the brand anchors and alter semantic role mappings, and an accent used as text takes the profile's accent-text role rather than its fill role.",
          "acceptance": "Theme switches retain layout, focus, selection and data. Red never flashes white/cyan on entry, dialogs or loading. Dark controls use dark on-action text; the existing Daylight Ember requires dark text, not assumed white. Test astronomy text on its action fill.",
          "url": "https://simt.space/cosmos-design/common#c06"
        },
        {
          "id": "C29",
          "title": "One colour truth, two notations",
          "level": "must",
          "requirement": "Author and verify colour in sRGB and publish an oklch projection for the web parts. The anchors, gradients, shadows and semantic roles stay sRGB in the specification, because contrast is defined on sRGB luminance and every published contrast pair is measured there. Web tokens may be written in oklch from the projection in platformAdapters, so one role can step lightness without re-picking a hue. Android and Wear read sRGB: neither toolkit has an Oklab colour space, so a converted value would be a hex with extra steps.",
          "acceptance": "Every published web oklch resolves back to the sRGB value it came from within one 8-bit step, and every contrast claim is measured against the sRGB value. A colour is changed once, in hex, and both notations move together; no theme or component carries a colour absent from the registry.",
          "url": "https://simt.space/cosmos-design/common#c29"
        }
      ]
    },
    {
      "id": "light",
      "title": "Light with a job",
      "summary": "Eight gradients and two shadows. Each one is a named instrument, never a texture.",
      "platform": "common",
      "url": "https://simt.space/cosmos-design/common#light",
      "table": {
        "caption": "Gradient registry",
        "columns": ["Token", "Geometry", "Stops", "Job", "Profiles"],
        "rows": [
          [
            "gradient.field",
            "Radial 120% × 90% at 50% 0%",
            "void-edge → void @72%",
            "Root depth behind every Deep Space screen. Opaque, so text is measured against void-edge and void.",
            "deepSpace"
          ],
          [
            "gradient.nebula",
            "Radial 50% × 50% at 50% 50%",
            "violet 26% → rose 13% @36% → ember 6% @64% → ember 0%",
            "One atmospheric field per screen, behind the focal object or a section entry; never behind reading text.",
            "deepSpace"
          ],
          [
            "gradient.corona",
            "Radial 50% × 50% at 50% 50%",
            "gold 90% → ember 45% @14% → rose 12% @42% → rose 0%",
            "The only glow: the halo of the single focal object, painted in a box four to six times its diameter.",
            "deepSpace"
          ],
          [
            "gradient.accretion",
            "Conic from 0° at 50% 50%",
            "ember → gold @25% → rose @50% → violet @75% → ember",
            "A 1–2 px ring around the focal object. Never progress, status or a control outline.",
            "deepSpace"
          ],
          [
            "gradient.horizon",
            "Linear 90°",
            "ember 0% → ember @20% → gold @50% → violet @80% → violet 0%",
            "Light lines of 1–2 px: the top light of a surface, the horizon ribbon, a section signature.",
            "deepSpace, daylight"
          ],
          [
            "gradient.rim",
            "Linear 135°",
            "ember 55% → ink 10% @45% → violet 50%",
            "A 1 px border light for the focal or selected surface, beside its essential boundary rather than replacing it.",
            "deepSpace"
          ],
          ["gradient.action", "Linear 180°", "ember-soft → ember @55%", "Fill of the one primary action. The Void label passes on every stop.", "deepSpace"],
          [
            "gradient.spectrum",
            "Linear 90°",
            "ember → rose @20% → violet @40% → gold @60% → cyan @80% → moss",
            "The brand signature line. Category legends use solid labelled swatches instead.",
            "deepSpace, daylight"
          ]
        ]
      },
      "rules": [
        {
          "id": "C27",
          "title": "Gradient & glow grammar",
          "level": "must",
          "requirement": "Use only the published gradient and shadow tokens, each for its stated job: field for root depth, nebula for one atmospheric field, corona and accretion for the single focal object, horizon for 1–2 px light lines, rim for the border light of the focal or selected surface, action for the one primary action and spectrum for the brand signature. A screen has at most one corona, one accretion ring and one nebula. Light carries depth and focus, never status, selection or the only boundary, and text never takes a gradient fill. In Full tier the hero figure runs one ambient motion: the focal object's accretion disc revolves once every 40–90 s about the core, and every other light is static — including the accretion ring itself, because a boundary that moves stops being a boundary. Sky drift (C11) is the one alternative a screen may take instead. Deep Space uses the whole grammar, Daylight keeps horizon and spectrum, and astronomy red and watch ambient use none. A gradient token a profile does not run resolves to no gradient, so the element falls back to its flat role color instead of borrowing another profile's light.",
          "acceptance": "Every gradient and shadow in code resolves to a token name and its published geometry. Text over a gradient passes against every stop as an opaque pair. Removing all light leaves hierarchy, selection and boundaries intact. The revolving disc moves only `rotate` or `transform`, never a length, and is the only animation on the screen. Forced colors and astronomy red replace light with solid system or semantic borders.",
          "url": "https://simt.space/cosmos-design/common#c27"
        }
      ]
    },
    {
      "id": "atmosphere",
      "title": "Stars at the edge",
      "summary": "One deterministic sky per screen, generated the same way on every platform.",
      "platform": "common",
      "url": "https://simt.space/cosmos-design/common#atmosphere",
      "table": {
        "caption": "Atmosphere by surface",
        "columns": ["Surface", "Field & nebula", "Star layer", "Focal light", "Lines"],
        "rows": [
          [
            "Web page hero",
            "Field and one nebula behind the focal object",
            "Screen density; masked from the narrative column",
            "Corona and accretion on the emblem or selected record",
            "Horizon top light; spectrum signature"
          ],
          ["Web page reading", "Field only", "None", "None", "Horizon section signature"],
          [
            "Web app shell",
            "Field; no nebula",
            "Dialog density on sign-in, onboarding and empty states; never over a map or list",
            "Corona on the selected marker",
            "Horizon top light on the context pane"
          ],
          [
            "Mobile instrument",
            "Field and one Full-tier nebula",
            "Screen density, cached once per screen",
            "Corona and accretion on the target",
            "Horizon top light on sheets"
          ],
          ["Mobile sheet & dialog", "Inherits the screen field", "Dialog density", "None", "Horizon top light; rim on the focal sheet"],
          ["Mobile sky & orrery", "Field only", "None: every mark is data", "Corona on the selected body", "None"],
          ["Watch interactive", "Solid Void", "None", "One static corona on the bearing or target marker", "None"],
          ["Watch ambient", "Pure black", "None", "None", "None"],
          ["Daylight", "Flat background", "None", "None", "Horizon and spectrum"],
          ["Astronomy red", "Flat red background", "None", "None", "Solid red boundaries only"]
        ]
      },
      "rules": [
        {
          "id": "C11",
          "title": "One deterministic sky",
          "level": "must",
          "requirement": "A screen, hero, panel or dialog background may own one edge star layer from the published starfield algorithm: stars only in the outer 20% band, area / 7,500 stars clamped 24–160 for screens and area / 10,000 clamped 12–72 for dialogs, three magnitudes, at least 70% Ink, no accent above 10% and at most three diffraction-spiked stars. Seed it from a stable surface ID and a 160 px/dp size bucket. Drop stars within 16 px/dp of known text or controls after generation; never reseed to avoid them. Records, maps, media, data canvases, sky charts and watch screens own no stars.",
          "acceptance": "The same surface ID and bucket reproduce the published fixture on every platform. The layer is one cached bitmap, texture or compositor layer, never an element or view per star. Full tier may drift the whole layer once per 90–160 s by at most 1.5% of the shorter edge; Reduced, Static, Save-Data and hidden states freeze it, and low power draws 40% of the stars. Removing the layer changes no semantics or available task.",
          "url": "https://simt.space/cosmos-design/common#c11"
        }
      ]
    },
    {
      "id": "typography",
      "title": "Readable at every scale",
      "summary": "A confident display voice, with a quieter reading voice.",
      "platform": "common",
      "url": "https://simt.space/cosmos-design/common#typography",
      "table": {
        "caption": "Type roles; size / line height",
        "columns": ["Role", "Web", "Mobile", "Watch"],
        "rows": [
          ["Narrative display", "48–88 / 1.05, fluid rem", "40–48sp / 1.1, entry only", "Not used"],
          ["Primary instrument", "48–72 / 1.1", "48–64sp / 1.1", "32–40sp / 1.1"],
          ["Page title", "28–36 / 1.2", "28–32sp / 1.2", "18–20sp / 1.25"],
          ["Section title", "20–24 / 1.3", "20–24sp / 1.3", "16–18sp / 1.3"],
          ["Body", "16–18 / 1.6", "16sp / 1.5", "14–16sp / 1.4"],
          ["Supporting", "14 / 1.5", "14sp / 1.45", "12–14sp / 1.4"],
          ["Control label", "14–16 / 1.3", "14–16sp / 1.3", "14–16sp / 1.3"]
        ]
      },
      "rules": [
        {
          "id": "C07",
          "title": "Families & language",
          "level": "must",
          "requirement": "Use Space Grotesk for Latin titles and instrumentation, Source Sans 3 for web reading and form text, native system body type on Android, and El Messiri for Arabic roles. Bundle fonts, declare fallbacks and reserve fallback geometry. Use zero tracking by default; uppercase and spaced labels are Latin-only enhancements.",
          "acceptance": "No third-party font requests. Arabic has no mixed-script heading caused by an unsupported font. Font fallback and final font both retain unclipped text and controls.",
          "url": "https://simt.space/cosmos-design/common#c07"
        },
        {
          "id": "C08",
          "title": "Roles & number semantics",
          "level": "must",
          "requirement": "Use the roles below and rem/sp for text. Body line-height is 1.5–1.65; Arabic uses at least 1.6 with tested diacritic room. Reading columns are 55–72 characters. Instrument digits use tabular numerals, visible units and stable width; precision follows actual sensor/data accuracy.",
          "acceptance": "Web reflows at 400% on a 1280 CSS px viewport and text zoom at 200%; Android fontScale 2.0; watch largest system text. No essential label is clipped or replaced by an ellipsis-only value.",
          "url": "https://simt.space/cosmos-design/common#c08"
        }
      ]
    },
    {
      "id": "geometry",
      "title": "Field, spine, aperture",
      "summary": "Geometry should organize attention, not create visual noise.",
      "platform": "common",
      "url": "https://simt.space/cosmos-design/common#geometry",
      "table": {
        "caption": "Platform geometry mapping",
        "columns": ["Role", "Web page / web app", "Android", "Wear"],
        "rows": [
          ["Control — compact control, chip, field", "8 px", "8 dp", "round"],
          ["Secondary — inline affordance", "—", "10 dp", "—"],
          ["Emphasis — inline emphasis", "—", "14 dp", "—"],
          ["Record — card or list row", "16 px", "20 dp", "round"],
          ["Overlay — sheet or dialog", "24 px", "28 dp", "capsule"],
          ["Circle — instrument or compact icon control", "—", "round", "round"]
        ]
      },
      "rules": [
        {
          "id": "C09",
          "title": "Rhythm & mapped shape",
          "level": "must",
          "requirement": "Use 4, 8, 12, 16, 20, 24, 32, 40, 48, 64, 80, 96, 128 units. One unit is a CSS px or native dp, so the same numbers serve every platform and none of them publishes a spacing scale of its own. Take corner geometry from the platform mapping published in tokens.json rather than from a local scale: 8 px / 16 px / 24 px on web, 8 dp / 10 dp / 14 dp / 20 dp / 28 dp on Android, and the native round and capsule shapes on Wear, which publish no dp radius at all. A part that needs another role adds it to the mapping first. Circles denote instruments or compact icon controls, not paragraph containers.",
          "acceptance": "Spacing and shape map to named tokens, and a component's corner radius matches its role in the mapping for the part it ships in. No screen carries an ad-hoc px or dp corner value, and a native shape is expressed as the native shape rather than approximated with a number. The Wear layout fits its round screen instead of shrinking its targets. Small-screen compression first removes ornament and gutters; it does not shrink the readable type or hit target.",
          "url": "https://simt.space/cosmos-design/common#c09"
        },
        {
          "id": "C10",
          "title": "Surface budget",
          "level": "must",
          "requirement": "Use opaque Hull for reading and work. A panel, sheet or dialog may carry a horizon top light inset from its corners; only the focal surface adds a rim border. Canopy translucency is optional for one header or contextual overlay, with at least 88% opacity over imagery and an opaque fallback. Allow at most one backdrop blur region per visible screen, capped at 12px on web; disable it when measured costly. Borders establish hierarchy before light.",
          "acceptance": "The screen remains legible with blur unsupported or disabled. No live blur behind scrolling long copy, dialog inside a blurred sheet, or full-screen animated haze. Top light never touches a rounded corner at full intensity.",
          "url": "https://simt.space/cosmos-design/common#c10"
        },
        {
          "id": "C25",
          "title": "Icons, imagery & diagrams",
          "level": "must",
          "requirement": "Use one consistent icon family per platform: Lucide on web or the established native library. Standard marks are 20–24px/dp with a consistent stroke; the target remains 44px/48dp. Custom marks are reserved for concepts without a familiar equivalent. Images show the real object/place/person with a declared crop and reserved aspect ratio; diagrams have text equivalents.",
          "acceptance": "Decorative icons are hidden from assistive technology. Icon-only controls have localized names; unfamiliar commands retain visible labels. Mirror navigational arrows only. No duplicate icon font, raster text, misleading geographic imagery or unsupported scientific precision.",
          "url": "https://simt.space/cosmos-design/common#c25"
        },
        {
          "id": "C26",
          "title": "Layering & scroll ownership",
          "level": "must",
          "requirement": "Keep field, persistent chrome, contextual popover, modal and urgent feedback in that semantic order using a shared layer registry. Give each pane one scroll owner; the whole page reflows before adding nested scrolling. Bounded overflowing lists expose native scrolling and a visible edge/next-item or explicit navigation affordance. A fade cannot cover essential labels or intercept input.",
          "acceptance": "Popover/dialog/focus are never clipped by a record or overflow ancestor. Touch, wheel, keyboard and rotary reach all content. Scroll position and focus survive return from detail; closing a layer restores the correct owner. Reduced mode uses static scroll cues.",
          "url": "https://simt.space/cosmos-design/common#c26"
        }
      ]
    },
    {
      "id": "components",
      "title": "Component contracts",
      "summary": "The same behavior travels; shape and density adapt.",
      "platform": "common",
      "url": "https://simt.space/cosmos-design/common#components",
      "tables": [
        {
          "caption": "Shared state matrix",
          "columns": ["State", "Visible treatment", "Behavior / announcement", "Opted out by"],
          "rows": [
            ["Default · C12", "Opaque surface, legible label, essential boundary", "Real enabled semantics", "every component declares it"],
            ["Hover · C12", "Tonal lift; no movement of layout", "Optional; a pointer that cannot hover simply never shows it", "12 × notInteractive"],
            ["Pressed · C12", "Inset tone; no movement of layout", "Equivalent to hover for touch and keyboard", "7 × notInteractive"],
            ["Focus · C12, C19", "2px Gold ring + dark separation, 3px offset", "Visible, unclipped and not obscured by sticky UI", "10 × notFocusable"],
            ["Pending · C12", "Stable label and small progress mark", "Busy, duplicate guard; cancel if operation allows", "6 × notAsync"],
            ["Disabled · C12", "Muted label, disabled semantics, adjacent reason if useful", "No opacity reduction of all ancestor content", "10 × alwaysAvailable"],
            ["Error · C13, C16", "Danger icon, explicit text and retry", "Preserve safe inputs; error related to source", "10 × noFailureMode"],
            ["Confirmed · C12", "Success check and specific confirmation", "Retain durable result in the surface", "13 × confirmedElsewhere"],
            [
              "Selected · C12, C14",
              "Check, leading marker or tonal boundary; rim light may accompany, never replace it",
              "Selected / pressed / current state as appropriate",
              "13 × notSelectable"
            ],
            ["Stale · C16", "Muted surface and an age label beside the value", "The value stays readable and carries its age; never a pulse", "10 × notFetched"],
            [
              "Offline · C16",
              "Dimmed live surfaces and an offline notice with what is still available",
              "Cached content stays readable; recovery names the retry",
              "11 × notNetworkBound"
            ]
          ]
        },
        {
          "caption": "Component index",
          "columns": ["Component", "Rules"],
          "rows": [
            ["Primary action", "C12, C19, C26"],
            ["Secondary action", "C12, C19"],
            ["Destructive action", "C12, C15, C19"],
            ["Field with Clear", "C13, C19, C20"],
            ["Chips and selection", "C12, C14, C19"],
            ["Record row", "C14, C10, C19"],
            ["Sheet", "C15, C26, M07, C19"],
            ["Dialog", "C15, C19"],
            ["Banner", "C16, C21, C19"],
            ["Toast", "C16, C19"],
            ["Empty state", "C16, C01, C19"],
            ["Reading and stat", "C08, C21, C19"],
            ["Compass dial", "M03, M10, W06, C18, C19"],
            ["Target marker", "C18, M03, M05, W05, C27"],
            ["Context spine", "A02, C26, C10"],
            ["Horizon ribbon", "A04, C27, C26"],
            ["Watch action capsule", "W02, W05, W03, C19"]
          ]
        }
      ],
      "rules": [
        {
          "id": "C12",
          "title": "Actions & selection",
          "level": "must",
          "requirement": "Give a task region one visually dominant Ember action, filled with the action gradient and resting on the action shadow. Destructive actions use Danger and consequence-first confirmation where irreversible. Buttons expose default, hover, pressed, focus, pending, disabled, error and confirmed states. Selection uses shape/check plus aria-pressed, aria-selected or native semantics, while Gold focus is independent.",
          "acceptance": "Click/Enter/Space trigger once. Pending preserves the accessible name and width, exposes busy state and prevents duplicates. Confirm only after success; error restores safe retry without losing input.",
          "url": "https://simt.space/cosmos-design/common#c12"
        },
        {
          "id": "C13",
          "title": "Inputs & validation",
          "level": "must",
          "requirement": "Keep visible labels; connect hint, requirement, counter and error. Use real input/select/radio/checkbox/switch semantics. A nonempty editable single-line field exposes a 44px web/48dp native Clear button that returns focus to the field. Do not add it to password, read-only or disabled fields. Validate on submit or meaningful exit without announcing every keystroke.",
          "acceptance": "Keyboard autofill, paste, password managers, IME and RTL text work. Invalid fields expose invalid state and a text error; submit focuses the first error or linked error summary. Safe values survive retries.",
          "url": "https://simt.space/cosmos-design/common#c13"
        },
        {
          "id": "C14",
          "title": "Records & navigation",
          "level": "must",
          "requirement": "Keep records in aligned rows unless media/object identity justifies a card. Do not wrap nested links/buttons in another interactive target. Back follows history; Close dismisses a layer. Selected navigation combines label, boundary and programmatic current state. Navigation persists where the task does.",
          "acceptance": "Tab order matches reading order. Route navigation moves focus to a named destination heading; dialogs return focus to a surviving trigger. Back/forward restore filter, position and context as applicable.",
          "url": "https://simt.space/cosmos-design/common#c14"
        },
        {
          "id": "C15",
          "title": "Dialog, sheet & popover",
          "level": "must",
          "requirement": "Use one modal layer with a visible title, Close action, safe dismissal policy and actions in reading order. Web uses native dialog or an audited equivalent with focus containment, Escape and background inertness. Mobile uses platform back and inset-aware sheets. Popovers anchor to triggers and reflow before viewport clipping.",
          "acceptance": "Focus cannot enter the background of a modal. Unsaved edits get an explicit discard decision. Last action is reachable with the keyboard open and large text. Tooltips never contain the only critical instruction.",
          "url": "https://simt.space/cosmos-design/common#c15"
        },
        {
          "id": "C16",
          "title": "Feedback at the source",
          "level": "must",
          "requirement": "Use inline errors for local failures, a banner for screen-wide degraded state, and status/toast for confirmed transient results. Every primary surface designs first load, refresh/stale, empty, denied, offline, recoverable error, terminal unavailable and success. Loading reserves real geometry; shimmer is optional and never indefinite.",
          "acceptance": "Screen readers hear concise changes once; high-rate sensor updates are not live-announced each frame. Error copy says what happened, what remains safe and which action recovers. A toast is never the sole record of a failure.",
          "url": "https://simt.space/cosmos-design/common#c16"
        }
      ]
    },
    {
      "id": "motion",
      "title": "Motion earns its place",
      "summary": "Use movement to explain a change. Silence is a valid finish.",
      "platform": "common",
      "url": "https://simt.space/cosmos-design/common#motion",
      "tables": [
        {
          "caption": "Platform easing mapping",
          "columns": ["Purpose", "Web page / web app", "Android", "Wear"],
          "rows": [
            ["Standard — in-place transform and state", "cubic-bezier(0.2, 0, 0.2, 1)", "cubic-bezier(0.2, 0, 0.2, 1)", "cubic-bezier(0.2, 0, 0.2, 1)"],
            [
              "Arrival — emphasis and entrance",
              "cubic-bezier(0.22, 1, 0.36, 1); cubic-bezier(0.16, 0.84, 0.44, 1)",
              "cubic-bezier(0.05, 0.7, 0.1, 1)",
              "cubic-bezier(0.05, 0.7, 0.1, 1)"
            ],
            ["Departure — exit", "cubic-bezier(0.4, 0, 0.7, 0.2)", "cubic-bezier(0.3, 0, 0.8, 0.15)", "cubic-bezier(0.3, 0, 0.8, 0.15)"],
            ["Transform only", "—", "cubic-bezier(0.2, 0, 0, 1)", "cubic-bezier(0.2, 0, 0, 1)"]
          ]
        },
        {
          "caption": "Motion motifs",
          "columns": ["Motif", "Job", "Duration", "Easing", "Reduced"],
          "rows": [
            [
              "targetAcquired",
              "Tell the person that the thing they were tracking is now the thing they have.",
              "300ms local state",
              "standard, arrival",
              "Opacity only, over the feedback duration; the ring appears already at its final angle."
            ],
            [
              "listReveal",
              "Show that a set arrived, in an order a person can follow down.",
              "150ms feedback",
              "arrival",
              "Opacity only, staggered, over the feedback duration."
            ],
            [
              "horizonSweep",
              "Carry time or progress across a wide surface without a spinner.",
              "500ms context change",
              "standard",
              "The band is placed at its final position and its opacity resolves over the feedback duration; no travel."
            ],
            [
              "spineAdvance",
              "Move context forward one step, so the person always knows which step they are on.",
              "300ms local state",
              "standard",
              "The connector is placed at its final length and the two steps cross-resolve in opacity over the feedback duration."
            ],
            [
              "sheetRise",
              "Show which context a layer came from, and leave it dismissible.",
              "300ms local state",
              "arrival, departure",
              "The scrim resolves over the feedback duration and the surface is presented at its resting offset."
            ],
            [
              "dataStale",
              "Say that a reading is no longer fresh, without asking for attention.",
              "150ms feedback",
              "standard",
              "The dim resolves over the feedback duration, opacity only, once."
            ],
            [
              "routeChange",
              "Carry the reader from one context to the next without losing the frame.",
              "500ms context change",
              "arrival, departure",
              "Both resolve in opacity over the feedback duration, with no travel."
            ]
          ]
        }
      ],
      "rules": [
        {
          "id": "C17",
          "title": "Three effective tiers",
          "level": "must",
          "requirement": "Full uses 150ms feedback, 300ms local state, 500ms context change and the curve published for the part (C30). Reduced removes spatial travel and ambient loops; optional opacity feedback lasts at most 150ms. Static applies final state immediately. Explicit Static wins; reduced-motion, data saving, low power, thermal pressure and visibility can only lower the tier.",
          "acceptance": "Preference changes apply during the session. Full/Reduced/Static produce identical outcomes. Hidden screens and background tabs stop animation and sensor presentation. Hardware concurrency alone never determines ability or tier.",
          "url": "https://simt.space/cosmos-design/common#c17"
        },
        {
          "id": "C18",
          "title": "Progress & moving data",
          "level": "must",
          "requirement": "Animate transform/opacity for transitional UI, avoiding width/height/blur animation. Never auto-pan a map during a user gesture. Sensor smoothing cannot conceal stale/low-confidence data; separate visual interpolation from the stored/announced reading. Auto-updating content provides pause or stable inspection when applicable.",
          "acceptance": "No flashing beyond accessibility limits, parallax-dependent meaning, autoplay sound or attention-pulsing CTA. Reduced motion does not disable accurate data. Waiting is stated as text, not inferred from a spinner.",
          "url": "https://simt.space/cosmos-design/common#c18"
        },
        {
          "id": "C30",
          "title": "Easing is published per part",
          "level": "must",
          "requirement": "Use the easing set published for the part: web uses the standard curve with emphasis, entrance and exit for arriving and departing UI; Android and Wear use the standard curve with enter, exit and transform. Every part runs the same three durations; a part that needs another curve or duration publishes it in the mapping instead of defining one locally.",
          "acceptance": "Every transition resolves to a published curve, arrival and departure use opposite curves from the same set, and the reduced and static tiers still reach the final state without a curve. No component hard-codes a cubic-bezier, and a curve change is a mapping change rather than a silent divergence.",
          "url": "https://simt.space/cosmos-design/common#c30"
        },
        {
          "id": "C31",
          "title": "One motif per state change",
          "level": "must",
          "requirement": "Animate a state change by naming the published motif whose job is that change, and spend only the properties, duration and easing tokens that motif lists. A change with no motif does not animate. A new choreography is added as a motif with its own job rather than designed once inside a component. The motifs are published in motion.json, and the curve parity fixture in that document is how a native port proves it matches.",
          "acceptance": "Every animated state change names a motif, and every motif in motion.json is reachable from at least one surface. No motif animates a property outside its allowed list, and none loops or repeats to hold attention: stale data dims and gains a label. Reduced removes travel and keeps an opacity change within the feedback duration; Static settles immediately and reaches the same final state as Full. A port reproduces the sampled curve values to the published precision, or the mapping is wrong.",
          "url": "https://simt.space/cosmos-design/common#c31"
        }
      ]
    },
    {
      "id": "accessibility",
      "title": "Everyone keeps their bearings",
      "summary": "Input, language and physical access are part of the design.",
      "platform": "common",
      "url": "https://simt.space/cosmos-design/common#accessibility",
      "rules": [
        {
          "id": "C19",
          "title": "Access baseline",
          "level": "must",
          "requirement": "Target WCAG 2.2 AA on web and equivalent native behavior. Adopt 44×44 CSS px web targets and 48×48dp Android/Wear targets; design the round watch layout to fit rather than shrinking targets. Provide visible focus, names/roles/values, heading structure, error relationships, alternatives to dragging and a skip link.",
          "acceptance": "Complete primary flows with keyboard, touch and a screen reader. Focus is not covered by sticky chrome. Forced colors preserves borders, icons and focus; controls use system colors where needed.",
          "url": "https://simt.space/cosmos-design/common#c19"
        },
        {
          "id": "C20",
          "title": "Direction & localization",
          "level": "must",
          "requirement": "Use logical spacing and placement. Mirror navigation flow, never geography, north, compass mathematics or media playback. Isolate authored text, handles, coordinates and times. Localize visible copy, relative dates, plural counts, measurement units and accessible names. Persist unit preference independently of language.",
          "acceptance": "Test English, French, Arabic RTL and Spanish with long content and 200% expansion fixtures. Geographic points and bearing values are identical across directions. Critical facts remain readable in the full detail view.",
          "url": "https://simt.space/cosmos-design/common#c20"
        },
        {
          "id": "C21",
          "title": "Privacy & honest content",
          "level": "must",
          "requirement": "Represent accuracy, confidence, time zone, stale data, approximate location and permission state explicitly. Do not imply live data from decoration. Keep private coordinates, profile fields, draft text and sensitive actions out of URLs, crawled pages, analytics and error messages. Use illustrative labels for invented specimen data.",
          "acceptance": "Privacy decisions are explained at the action. Public previews reveal only authorized data. A denied or blocked profile does not disclose which private condition caused its unavailability.",
          "url": "https://simt.space/cosmos-design/common#c21"
        }
      ]
    },
    {
      "id": "implementation",
      "title": "Structured delivery & release",
      "summary": "Make the rules usable by people and machines.",
      "platform": "common",
      "url": "https://simt.space/cosmos-design/common#implementation",
      "table": {
        "caption": "Implementation content model",
        "columns": ["Field", "Required structure", "Purpose"],
        "rows": [
          ["Rule", "id, title, level, requirement, acceptance", "Stable conformance mapping"],
          ["Platform", "slug, description, sections, inheritance", "A bounded adapter with common dependencies"],
          ["Token", "$type, $value, $description; semantic adapter", "Typed values; explicit units and color space"],
          ["Screen brief", "task, privacy class, layout, states, input, data, rules", "Enough context to implement without guessing"],
          ["Evidence", "version, build, route, environment, result, owner", "Traceable release decision"]
        ]
      },
      "rules": [
        {
          "id": "C22",
          "title": "One source & stable addresses",
          "level": "must",
          "requirement": "Maintain this specification in cosmos/. Generate HTML, plain Markdown, the typed token file and the complete specification JSON together. Stable rule IDs and section URLs are public contracts, and each part publishes its own tokens and rules payload carrying the common foundations plus only its own adapter. Return real files with correct MIME types; machine requests must not silently receive the home page.",
          "acceptance": "Generated-output drift fails verification. All routes, anchors, cross-links and downloads resolve in development, preview and production. Manifest includes version, status, scope, assets, platform inheritance and source provenance. A part payload is byte-identical to the canonical documents for everything it shares, carries exactly one adapter, and stays inside its published byte budget, so it cannot drift back into the union. A document needed only sometimes keeps its own address: composited contrast measurements are fetched from contrast-pairs.json instead of being embedded in a payload, and every published document states when to fetch it.",
          "url": "https://simt.space/cosmos-design/common#c22"
        },
        {
          "id": "C23",
          "title": "Performance is measured",
          "level": "must",
          "requirement": "Use the platform budgets and release matrices. Web field targets are p75 LCP ≤2.5s, INP ≤200ms and CLS ≤0.1 for mobile and desktop cohorts. Lab tests are diagnostic, not a substitute for field results. Record route, build, device, browser/OS, network, locale, motion tier and method with evidence.",
          "acceptance": "A release has a named owner and real measurements. Visual specifications and mockups are never labeled proof that unimplemented products meet their runtime targets.",
          "url": "https://simt.space/cosmos-design/common#c23"
        },
        {
          "id": "C24",
          "title": "Conformance & maintenance",
          "level": "must",
          "requirement": "Release only after applicable rules pass contrast, input, localization, state and performance checks. Record exceptions with affected rule, product reason, accessible alternative, owner and expiry. A palette or semantic-rule change requires a version update and migration note; minor additions preserve stable IDs.",
          "acceptance": "The release record links screenshots, accessibility findings, performance traces and resolved defects. Core maintainers review shared changes; platform maintainers review adapter changes. Broken required flows block acceptance.",
          "url": "https://simt.space/cosmos-design/common#c24"
        }
      ]
    },
    {
      "id": "shell",
      "title": "A persistent social field",
      "summary": "Preserve spatial context without trapping people in a map.",
      "platform": "web-app",
      "url": "https://simt.space/cosmos-design/web-app#shell",
      "rules": [
        {
          "id": "A01",
          "title": "Shell geometry",
          "level": "must",
          "requirement": "At ≥1200px use a 216px labeled rail, flexible discovery field and a 360–420px context pane when selected. At 768–1199px use a 72px rail with accessible names and a 320–360px detail overlay. Below 768px use a 56px top context bar and a ≥64px bottom dock plus safe area. Map/list is a labeled mode switch, not a separate feature implementation.",
          "acceptance": "Dock and rail show Discover, Inbox, Saved and Profile; create remains one stable primary command. The shell accommodates large text through vertical growth or a labeled collapsed layout, never label clipping.",
          "url": "https://simt.space/cosmos-design/web-app#a01"
        },
        {
          "id": "A02",
          "title": "Context spine",
          "level": "must",
          "requirement": "Place location scope, active time/filter summary and result count on one stable context spine. Selected detail begins with identity, date/time, place precision and participation state; the primary action follows those facts. Keep maps mounted across sheets when geography is part of the task, but release inactive hidden routes.",
          "acceptance": "Closing detail restores the previous selected marker/list row, focus and scroll. Browser back restores context. Filters and result count agree across map and list; manual map exploration never silently turns on follow-location.",
          "url": "https://simt.space/cosmos-design/web-app#a02"
        }
      ]
    },
    {
      "id": "discovery",
      "title": "Discover by place, time or people",
      "summary": "Dense information, with calm priority.",
      "platform": "web-app",
      "url": "https://simt.space/cosmos-design/web-app#discovery",
      "rules": [
        {
          "id": "A03",
          "title": "Map & list parity",
          "level": "must",
          "requirement": "Use Petrol land and Water, warm low-contrast roads and labeled category markers. Clusters show counts, the selected marker gets the quasar aperture and a label, current location shows confidence radius plus text. Render map objects with native map layers/feature state; expose the same authorized results in a semantic list. Location permission is requested only when needed.",
          "acceptance": "Every meaningful map action has a list/keyboard equivalent. Marker targets expand to 44px; overlaps resolve through clusters or a chooser. Attribution is visible and not covered. Unavailable tiles leave a useful list and retained filters.",
          "url": "https://simt.space/cosmos-design/web-app#a03"
        },
        {
          "id": "A04",
          "title": "Horizon ribbon",
          "level": "must",
          "requirement": "Order activity results by actual local start time with visible date groups and explicit time zone when relevant. A compact time ribbon may select a range, paired with an editable date/time control and result summary. Live/stale labels refer to the real data freshness policy, not animation.",
          "acceptance": "DST, past/current/upcoming and locale dates are correct. Manual keyboard/touch date selection is possible. Zero matches explains the active scope and offers reset without discarding unrelated choices.",
          "url": "https://simt.space/cosmos-design/web-app#a04"
        },
        {
          "id": "A05",
          "title": "Activity record",
          "level": "must",
          "requirement": "Display title, date/time, coarse place, role/category, participation/capacity and owner identity in stable tracks. One primary target opens details; Save and other commands are separate controls. Image ratio is 3:2 for a media card; text rows remain a valid low-data representation.",
          "acceptance": "Long titles wrap to two lines in summary with the full value in detail. Missing images have a purposeful placeholder. Loading, zero results, denied data, offline cached results and removed activities keep a coherent layout.",
          "url": "https://simt.space/cosmos-design/web-app#a05"
        }
      ]
    },
    {
      "id": "participation",
      "title": "Honest participation",
      "summary": "An action is meaningful only when its result is clear.",
      "platform": "web-app",
      "url": "https://simt.space/cosmos-design/web-app#participation",
      "rules": [
        {
          "id": "A06",
          "title": "Detail & participation states",
          "level": "must",
          "requirement": "Design available, pending approval, confirmed, waitlisted, full, cancelled, finished and unavailable states where the backend supports them. Distinguish requesting participation from being accepted. Place consequences, privacy and location precision beside the action. Do not invent a backend capability to satisfy a visual.",
          "acceptance": "The UI maps each supported server state explicitly; unsupported target capabilities are recorded as contract dependencies. Pending mutation is guarded, failure rolls back safely, and confirmed counts come from authoritative data.",
          "url": "https://simt.space/cosmos-design/web-app#a06"
        },
        {
          "id": "A07",
          "title": "Saved, profile & inbox",
          "level": "must",
          "requirement": "Reuse record geometry for Saved; profile opens with identity and authorized roles before activity rows. Inbox separates actionable unread events from history, with text and a leading marker rather than glow. Timeline messages preserve drafts on failure and retain read-only/removed/access-revoked states.",
          "acceptance": "Read/unread changes update counts consistently. Public profiles are permission-safe. Owner-only controls are absent for other users; denied routes provide recovery without leaking private conditions.",
          "url": "https://simt.space/cosmos-design/web-app#a07"
        }
      ]
    },
    {
      "id": "composer",
      "title": "Compose with continuity",
      "summary": "Keep the idea intact while people solve the details.",
      "platform": "web-app",
      "url": "https://simt.space/cosmos-design/web-app#composer",
      "rules": [
        {
          "id": "A08",
          "title": "Four-step composer",
          "level": "must",
          "requirement": "Use Idea → Moment → Place → Review, an always-readable progress spine and a concise draft summary. Each step validates its owned fields; users can go back without losing safe values. Preserve product capacity/range limits from the real API contract. Show exact/approximate place choice and its audience consequences in Place and Review.",
          "acceptance": "No false autosave claim: label saved only after the supported persistence succeeds. Draft resume, discard, upload progress/failure, permission denial, version conflict and submit failure are designed. Review displays the exact publish audience and location precision.",
          "url": "https://simt.space/cosmos-design/web-app#a08"
        },
        {
          "id": "A09",
          "title": "Forms & destructive changes",
          "level": "must",
          "requirement": "Use a 640px reading/form maximum, stable labels and grouped sections separated by rules. Sticky submit belongs to the form and respects keyboard/safe area. Confirm deletion with object name and consequence, without coercive wording. For stale concurrent edits, present an explicit refresh/review choice and preserve the local draft.",
          "acceptance": "Submission errors link to fields; network failure retains input. Double activation cannot create two activities. Disabled controls state the unmet requirement when a person can resolve it.",
          "url": "https://simt.space/cosmos-design/web-app#a09"
        }
      ]
    },
    {
      "id": "operations",
      "title": "A precise operational console",
      "summary": "The same palette, with quieter structure and stronger evidence.",
      "platform": "web-app",
      "url": "https://simt.space/cosmos-design/web-app#operations",
      "rules": [
        {
          "id": "A10",
          "title": "Moderation & administration",
          "level": "must",
          "requirement": "Use semantic tables with direct status labels, stable column alignment, consequence summaries and traceable decisions. Separate queue, subject evidence and decision area; never put each cell in a card. Honor the existing desktop-only moderation policy on compact widths with a useful desktop-required explanation.",
          "acceptance": "Unauthorized tools do not render. Permission revocation fails closed. Conflict, stale evidence, audit failure and terminal state block unsafe actions. Sensitive evidence never appears in public previews, telemetry or exports without authorization.",
          "url": "https://simt.space/cosmos-design/web-app#a10"
        }
      ]
    },
    {
      "id": "performance",
      "title": "A responsive working set",
      "summary": "Responsiveness includes memory, map work and recovery.",
      "platform": "web-app",
      "url": "https://simt.space/cosmos-design/web-app#performance",
      "rules": [
        {
          "id": "A11",
          "title": "Loading & runtime budgets",
          "level": "must",
          "requirement": "Target ≤180KiB gzip initial app JavaScript excluding the deferred map engine, ≤50KiB gzip shared CSS and ≤120KiB initial fonts. Render a useful list/shell before map readiness; defer admin/composer/media code. Bound visible records, images and map sources to the task; virtualization must preserve accessibility, focus and findability.",
          "acceptance": "On a named baseline device, repeated filter/detail/back cycles do not cause monotonic retained-memory growth. Map and list retain selection. Long tasks are diagnosed; field Core Web Vitals meet common targets before release acceptance.",
          "url": "https://simt.space/cosmos-design/web-app#a11"
        },
        {
          "id": "A12",
          "title": "Secure rendering & recovery",
          "level": "must",
          "requirement": "SSR public content and safe shell data only; authenticate before rendering private payloads. Authenticated responses default to private, no-store unless a reviewed isolation policy permits caching. Offline data is shown only when policy permits, with timestamp and safe recovery. Never trade data isolation for instant-looking transitions.",
          "acceptance": "Multi-account switching cannot reveal previous private data. Rendered errors are localized and safe; technical error IDs may appear only as support metadata. Retry is bounded and cancel/abort is respected.",
          "url": "https://simt.space/cosmos-design/web-app#a12"
        }
      ]
    },
    {
      "id": "release",
      "title": "Web app acceptance",
      "summary": "Ship a complete task slice, including the hard states.",
      "platform": "web-app",
      "url": "https://simt.space/cosmos-design/web-app#release",
      "rules": [
        {
          "id": "A13",
          "title": "Route matrix",
          "level": "must",
          "requirement": "Review sign-in/onboarding, map/list discovery, detail/participation, create/edit, saved, inbox/timeline, profile/settings, account states, share/unavailable and authorized admin routes. Compare 390, 768, 1024 and 1440px, Arabic RTL, large text, forced colors and every motion tier. Exercise keyboard and screen-reader flows with real supported contract fixtures.",
          "acceptance": "Evidence names the direct composition, build and tested routes. A missing denied/offline/conflict state or inaccessible map-only task blocks the affected feature; unrelated routes are not claimed validated.",
          "url": "https://simt.space/cosmos-design/web-app#a13"
        }
      ]
    }
  ]
}
