/* ============================================================
   MUSIMEE · DESIGN TOKENS  ·  v2.0  ·  SINGLE LIGHT THEME
   ------------------------------------------------------------
   Source of truth: musimee-brand-kit (Ink · Paper · Stone · Signal).
   Scales derived in OKLab from the 4 official colours.
   Every contrast pair was calculated — the values are annotated.
   There is NO dark mode. A dark background is a section DEVICE (.on-ink),
   not a theme. See docs/00-foundation/color.md.
   ============================================================ */

@import url('https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@500;700&family=DM+Sans:opsz,wght@9..40,400;9..40,500;9..40,600&family=Instrument+Serif:ital@0;1&display=swap');

:root {
  /* == 1. BRAND ANCHORS (immutable - from the brand kit) ====== */
  --m-ink:    #2B2926;   /* text, symbol, dark backgrounds */
  --m-paper:  #F7F4EC;   /* base background */
  --m-stone:  #DAD6CD;   /* dividers, support */
  --m-signal: #F0793B;   /* accent — 1 per piece */

  /* == 2. SIGNAL SCALE (orange) ==============================
     Measured contrast · P = on Paper · I = Ink on the colour      */
  --m-signal-50:  #FFEEDD;  /* P 1.03 · highlight background     */
  --m-signal-100: #FFDFC7;  /* P 1.15 · soft chip                */
  --m-signal-200: #FFC8A5;  /* P 1.36 · highlight border         */
  --m-signal-300: #FFAC7F;  /* P 1.67 · gradient / illustration  */
  --m-signal-400: #FF9059;  /* P 2.04 · gradient                 */
  --m-signal-500: #F0793B;  /* BRAND · Ink on it 5.18 AA-OK      */
  --m-signal-600: #D9621C;  /* P 3.34 AA-large / icon / border   */
  --m-signal-700: #B44A02;  /* P 4.87 · alt 4.70 · surf 5.33 AA-OK text and link */
  --m-signal-800: #953B00;  /* P 6.58 · strong text              */
  --m-signal-900: #752D00;  /* P 8.96                            */
  --m-signal-950: #521F02;  /* P 12.28                           */

  /* == 3. WARM NEUTRAL SCALE (Paper -> Ink) ==================
     Not framework grey: 50 = Paper, 900 = Ink, exactly.          */
  --m-neutral-0:   #FFFFF7;  /* P 1.09 · surface above the paper   */
  --m-neutral-50:  #F7F4EC;  /* = Paper                            */
  --m-neutral-100: #F3F0E8;  /* P 1.04 · alternating band          */
  --m-neutral-200: #E2DFD8;  /* P 1.21 · default border            */
  --m-neutral-300: #D2CFC8;  /* P 1.42 · strong border (Stone's neighbour) */
  --m-neutral-400: #ACA9A3;  /* P 2.13 · decorative, NEVER text    */
  --m-neutral-500: #8A8782;  /* P 3.26 · alt 3.14 · icon, placeholder */
  --m-neutral-600: #6E6C67;  /* P 4.77 · alt 4.61 AA-OK · muted floor  */
  --m-neutral-700: #595652;  /* P 6.64 AA-OK · body text           */
  --m-neutral-800: #403E3B;  /* P 9.70 AA-OK                       */
  --m-neutral-900: #2B2926;  /* = Ink · P 13.20 AA-OK              */
  --m-neutral-950: #191714;  /* P 16.27 · editorial black          */

  /* == 4. SEMANTIC (all >=4.5 on Paper and with white) ======== */
  --m-success:      #186B41;  /* P 5.94 */
  --m-success-soft: #E4F0E8;
  --m-warning:      #9A5200;  /* P 5.34 — earth amber, NEVER gold    */
  --m-warning-soft: #FBEBD6;
  --m-danger:       #A82F2A;  /* P 6.15 */
  --m-danger-soft:  #F8E5E2;
  --m-info:         #2A6B87;  /* P 5.38 */
  --m-info-soft:    #E3EEF3;

  /* == 5. SEMANTIC ROLES · ALWAYS use these, never the hex ==== */
  /* surface */
  --m-bg:             var(--m-paper);
  --m-bg-alt:         var(--m-neutral-100);
  --m-surface:        var(--m-neutral-0);
  --m-surface-alt:    var(--m-neutral-100);
  --m-surface-ink:    var(--m-ink);
  --m-surface-signal: var(--m-signal-500);

  /* text on a light surface */
  --m-text:       var(--m-neutral-900);  /* headings            */
  --m-text-body:  var(--m-neutral-700);  /* paragraph           */
  --m-text-muted: var(--m-neutral-600);  /* secondary (AA floor)*/
  --m-text-faint: var(--m-neutral-500);  /* icon/placeholder    */
  --m-text-link:  var(--m-signal-700);   /* 4.87 · underlined   */

  /* text on a dark or orange surface */
  --m-text-on-ink:       var(--m-paper);   /* 13.20 */
  --m-text-on-ink-body:  #DDD8CE;          /* 10.40 on Ink */
  --m-text-on-ink-muted: #A9A49A;          /*  6.10 on Ink */
  --m-text-on-signal:    var(--m-ink);     /*  5.18 */

  /* borders */
  --m-border:        var(--m-neutral-200);
  --m-border-strong: var(--m-stone);
  --m-border-soft:   rgba(43, 41, 38, 0.07);
  --m-border-ink:    rgba(247, 244, 236, 0.16);   /* inside .on-ink */

  /* accent */
  --m-accent:      var(--m-signal-500);   /* fill, chart                  */
  --m-accent-text: var(--m-signal-700);   /* text/link/icon on paper      */
  --m-accent-line: var(--m-signal-600);   /* decorative border/underline  */
  --m-accent-wash: var(--m-signal-50);    /* soft background              */

  /* visible focus (a11y) */
  --m-focus: 0 0 0 3px rgba(240, 121, 59, 0.45), 0 0 0 1px var(--m-ink);

  /* == 6. TYPOGRAPHY ========================================== */
  --m-font-display: 'Space Grotesk', system-ui, sans-serif;  /* headings + logo  */
  --m-font:         'DM Sans', system-ui, sans-serif;        /* body + UI        */
  --m-font-mono:    'DM Mono', ui-monospace, monospace;      /* numbers, eyebrow */
  --m-font-voice:   'Instrument Serif', Georgia, serif;      /* ONLY song lyrics and quoted memories */

  /* fluid scale — landing */
  --m-fs-hero:    clamp(2.75rem, 1.4rem + 6.2vw, 6rem);
  --m-fs-display: clamp(2.25rem, 1.3rem + 4.4vw, 4.25rem);
  --m-fs-h1:      clamp(1.9rem,  1.2rem + 3.0vw, 3rem);
  --m-fs-h2:      clamp(1.5rem,  1.1rem + 1.9vw, 2.25rem);
  --m-fs-h3:      clamp(1.25rem, 1.05rem + 0.9vw, 1.5rem);
  --m-fs-h4:      1.125rem;
  /* fixed scale — product (predictable density) */
  --m-fs-xs:   0.75rem;
  --m-fs-sm:   0.8125rem;
  --m-fs-base: 0.9375rem;
  --m-fs-md:   1rem;
  --m-fs-lg:   1.125rem;
  --m-fs-xl:   1.375rem;

  --m-lh-hero:   0.98;
  --m-lh-tight:  1.08;
  --m-lh-snug:   1.25;
  --m-lh-normal: 1.6;   /* body — brand kit rule */
  --m-lh-loose:  1.75;

  --m-ls-logo:    -0.05em;
  --m-ls-display: -0.04em;
  --m-ls-heading: -0.03em;
  --m-ls-body:    -0.01em;
  --m-ls-eyebrow:  0.16em;   /* mono uppercase */

  --m-fw-light:    300;
  --m-fw-regular:  400;
  --m-fw-medium:   500;
  --m-fw-semibold: 600;
  --m-fw-bold:     700;   /* ONLY display and logo */

  /* == 7. SPACING (baseline 4) ================================ */
  --m-1: 4px;    --m-2: 8px;    --m-3: 12px;  --m-4: 16px;
  --m-5: 20px;   --m-6: 24px;   --m-8: 32px;  --m-10: 40px;
  --m-12: 48px;  --m-16: 64px;  --m-20: 80px; --m-24: 96px;
  --m-32: 128px; --m-40: 160px;

  /* vertical section breathing — the landing breathes, the product does not */
  --m-section-y:       clamp(64px, 9vw, 160px);
  --m-section-y-tight: clamp(40px, 5vw, 80px);
  --m-block-gap:       clamp(24px, 3.5vw, 56px);

  /* == 8. LAYOUT ============================================== */
  --m-container:      1200px;
  --m-container-wide: 1400px;
  --m-content:        680px;   /* reading measure ~68ch */
  --m-narrow:         520px;
  --m-gutter:         clamp(20px, 5vw, 64px);
  --m-touch:          44px;
  /* breakpoints (documented constants — a CSS var does not work in @media)
     sm 480 · md 768 · lg 1024 · xl 1280 · 2xl 1440 */

  /* == 9. RADII =============================================== */
  --m-r-xs:   6px;
  --m-r-sm:   10px;
  --m-r:      12px;
  --m-r-md:   16px;
  --m-r-lg:   22px;
  --m-r-xl:   32px;
  --m-r-2xl:  44px;
  --m-r-pill: 999px;
  --m-r-icon: 22%;    /* app icon (squircle) */

  /* == 10. SHADOWS — warm light, never blue-grey ============== */
  --m-sh-xs: 0 1px 2px rgba(43,41,38,0.05);
  --m-sh-sm: 0 2px 6px rgba(43,41,38,0.06);
  --m-sh:    0 8px 20px -6px rgba(43,41,38,0.10), 0 2px 6px rgba(43,41,38,0.05);
  --m-sh-md: 0 18px 40px -12px rgba(43,41,38,0.16), 0 4px 10px rgba(43,41,38,0.05);
  --m-sh-lg: 0 36px 80px -24px rgba(43,41,38,0.24), 0 8px 20px rgba(43,41,38,0.06);
  --m-sh-signal: 0 12px 32px -10px rgba(240,121,59,0.55);
  --m-sh-inset:  inset 0 1px 0 rgba(255,255,255,0.6);

  /* == 11. MOTION ============================================= */
  --m-ease:        cubic-bezier(0.22, 1, 0.36, 1);   /* out-quint · default */
  --m-ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
  --m-ease-spring: cubic-bezier(0.34, 1.42, 0.52, 1);
  --m-t-instant: 120ms var(--m-ease);
  --m-t-fast:    200ms var(--m-ease);
  --m-t:         320ms var(--m-ease);
  --m-t-slow:    560ms var(--m-ease);
  --m-t-scene:   900ms var(--m-ease);   /* ONLY landing (narrative motion) */

  /* == 12. TEXTURE — the "life" of the expressive layer ======= */
  --m-grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='0.42'/%3E%3C/svg%3E");
  --m-glow-warm: radial-gradient(60% 55% at 50% 0%, rgba(240,121,59,0.16), transparent 70%);
  --m-glow-soft: radial-gradient(50% 50% at 80% 20%, rgba(255,172,127,0.22), transparent 70%);
}

/* == DARK-BACKGROUND SECTION =================================
   Not dark mode. It is a section of breathing room inside the light page.
   Put .on-ink on the <section> and the text/border tokens flip. */
.on-ink {
  background: var(--m-ink);
  --m-text:       var(--m-paper);
  --m-text-body:  #DDD8CE;   /* 10.4 on ink */
  --m-text-muted: #A9A49A;   /*  6.1 on ink */
  --m-text-faint: #807B72;   /*  3.5 on ink — non-text */
  --m-text-link:  var(--m-signal-500);  /* 5.18 */
  --m-accent-text: var(--m-signal-500);
  --m-surface:     #35322E;
  --m-surface-alt: #3E3A35;
  --m-border:        var(--m-border-ink);
  --m-border-strong: rgba(247,244,236,0.28);
  --m-border-soft:   rgba(247,244,236,0.09);
  color: var(--m-text-body);
}

/* == ORANGE SECTION ==========================================
   Text is ALWAYS Ink (5.18). White on signal FAILS (2.80). */
.on-signal {
  background: var(--m-signal-500);
  --m-text:       var(--m-ink);
  --m-text-body:  #3A2716;
  --m-text-muted: #412810;
  --m-text-link:  var(--m-ink);
  --m-surface:    rgba(255,255,255,0.85);
  --m-border:        rgba(43,41,38,0.22);
  --m-border-strong: rgba(43,41,38,0.4);
  color: var(--m-text-body);
}

/* == MINIMAL RESET + BASE ==================================== */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  background: var(--m-bg);
  color: var(--m-text-body);
  font-family: var(--m-font);
  font-size: var(--m-fs-md);
  line-height: var(--m-lh-normal);
  letter-spacing: var(--m-ls-body);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
h1, h2, h3, h4 {
  font-family: var(--m-font-display);
  font-weight: var(--m-fw-bold);
  letter-spacing: var(--m-ls-display);
  line-height: var(--m-lh-tight);
  color: var(--m-text);
  margin: 0;
  text-wrap: balance;
}
p { margin: 0; text-wrap: pretty; }
img, svg, video { max-width: 100%; height: auto; display: block; }
a { color: var(--m-text-link); }
p a, li a { text-decoration: underline; text-underline-offset: 0.18em; }
:focus-visible { outline: none; box-shadow: var(--m-focus); border-radius: var(--m-r-xs); }
::selection { background: var(--m-signal-200); color: var(--m-ink); }

/* == SCROLLBAR ===============================================
   The default bar is cold grey and reads as the operating system's, not the
   brand's. On a warm cream page it is the one element that looks borrowed.

   A scrollbar thumb IS an interface component, so it needs 3:1 against the
   surface behind it (WCAG 1.4.11). That rules out every obvious pick —
   measured on Paper and on the alternating band, the worst of the two:

     Stone       #DAD6CD   1.27   fails
     neutral-300 #D2CFC8   1.37   fails
     neutral-400 #ACA9A3   2.06   fails
     signal-500  #F0793B   2.46   fails   <- the brand orange, as a UI element
     neutral-500 #8A8782   3.14   PASSES  <- rest
     signal-600  #D9621C   3.23   PASSES  <- hover

   Which lands exactly on the rule in docs/00-foundation/color.md:
   500 fills, **600 draws**, 700 writes. A scrollbar thumb is drawn, so the
   accent it reaches for on hover is the 600, never the 500.

   The resting colour also clears Ink (4.05), so the bar stays legible while
   the page is scrolled through an .on-ink section.

   The thumb is a pill, like every other control in the system — see
   docs/00-foundation/radii-shadows.md. The transparent border plus
   background-clip is what gives it breathing room inside the gutter instead
   of a slab filling the full width; the hit area stays the full 12px. */
/* THE STANDARD PROPERTIES ONLY WHERE THE WEBKIT ONES ARE UNKNOWN: Chrome
   and Safari honour them and then ignore every ::-webkit-scrollbar rule
   below, drawing a thin grey channel with arrow buttons instead of the
   pill described above. Firefox has no ::-webkit-scrollbar, so it alone
   takes these — and draws the same colours its own way. */
@supports not selector(::-webkit-scrollbar) {
  html {
    scrollbar-width: thin;
    scrollbar-color: var(--m-neutral-500) transparent;
  }
}
::-webkit-scrollbar { width: 12px; height: 12px; }
::-webkit-scrollbar-button { display: none; width: 0; height: 0; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  background: var(--m-neutral-500);
  border-radius: var(--m-r-pill);
  border: 3px solid transparent;
  background-clip: content-box;
}
::-webkit-scrollbar-thumb:hover { background: var(--m-signal-600); background-clip: content-box; }
::-webkit-scrollbar-corner { background: transparent; }

/* numbers always aligned in a table/KPI/price */
/* DM Mono was dropped: it served 4 duration labels and cost a whole font
   family. tabular-nums aligns the digits just the same. */
.m-num { font-variant-numeric: tabular-nums; font-feature-settings: 'tnum' 1; }

/* == SHARED KEYFRAMES ======================================== */
@keyframes m-rise    { from { opacity: 0; transform: translateY(22px); } to { opacity: 1; transform: none; } }
@keyframes m-fade    { from { opacity: 0; } to { opacity: 1; } }
@keyframes m-shimmer { 0% { background-position: 100% 0; } 100% { background-position: -100% 0; } }
@keyframes m-pulse   { 0%, 100% { opacity: 1; } 50% { opacity: .45; } }
@keyframes m-bar     { 0%, 100% { transform: scaleY(0.28); } 50% { transform: scaleY(1); } }
@keyframes m-marquee { from { transform: translateX(0); } to { transform: translateX(-50%); } }
@keyframes m-toast   { from { opacity: 0; transform: translateY(14px) scale(.97); } to { opacity: 1; transform: none; } }

/* == SKELETON =================================================
   For content that is not there YET — a request in flight — and for nothing
   else. An image whose bytes are coming does not want this: it wants a blur of
   itself (see the hero band), because a grey rectangle pulsing where a
   photograph will be is less information than the photograph's own colours.

   THE SHAPE IS THE POINT. A skeleton that does not match what replaces it is
   just a loading spinner drawn as a box: the eye settles on a layout, then the
   layout changes, and the second arrangement costs more attention than a
   blank space would have. So these are primitives to be composed per screen —
   a line, a block, a circle — not one generic card.

   It carries its own accessibility: aria-hidden, because a screen reader
   should be told "loading" once by the live region, not read a wall of empty
   boxes.

   m-shimmer already existed in this file and nothing used it. */
.m-skel {
  position: relative;
  overflow: hidden;
  background: var(--m-neutral-100, #EFEBE2);
  border-radius: var(--m-radius-sm, 8px);
}

.m-skel::after {
  content: '';
  position: absolute;
  inset: 0;
  /* Travels across, catching the light. 1.4s is slow enough to read as
     "working" rather than as a strobe. */
  background: linear-gradient(90deg,
    transparent 0%,
    rgba(255, 255, 255, .58) 50%,
    transparent 100%);
  background-size: 200% 100%;
  animation: m-shimmer 1.4s ease-in-out infinite;
}

/* A line of text. The last one is short, because the last line of a paragraph
   is short — a stack of identical full-width bars reads as a table. */
.m-skel--line   { height: 1em; border-radius: 4px; }
.m-skel--line:last-child { width: 62%; }
.m-skel--title  { height: 1.6em; border-radius: 6px; width: 72%; }
.m-skel--circle { border-radius: 50%; aspect-ratio: 1; }
.m-skel--block  { border-radius: var(--m-radius-md, 12px); aspect-ratio: 1; }

/* Stacks of lines need air between them or they read as one grey mass. */
.m-skel-lines { display: grid; gap: .5em; }

/* Nothing moves for somebody who asked for less motion — but the shape stays,
   because the shape is what says "something is coming". */
@media (prefers-reduced-motion: reduce) {
  .m-skel::after { animation: none; opacity: .35; }
}

/* == ACCESSIBILITY · non-negotiable ========================== */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}
.m-sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
