/* public/eccm.css: a reading site for a contemporary music centre, laid out
   like eccm.ee's own front page and set in the face that page really draws.
   Nothing here comes from shell.css and nothing here is read by it. The tokens
   are plans/plan-eccm-design.md §D; the rules that carry over from
   positron-compose are §1 (air belongs to the relationship), §2 (one grid),
   §4 (rows tinted, never lined), §6 (a start row wraps as a cluster) and §8
   (@layer on line one). */
@layer reset, base, layout, components, page;

/* ── the typeface: Schibsted Grotesk ─────────────────────────────────────────
   Chosen 2026-09-26 as "Use font e" off ./type.html, where seven setups were
   shown in the page's own sizes. Before that the page used the machine's
   Helvetica, which is what eccm.ee draws (it declares Roboto and serves
   nothing), and the owner called the result rough. Two variable files, latin
   and latin-ext (Š and Ž live in the second), fetched once from Google's
   static host, SIL OFL beside them in ./vendor/, served from here; the page
   asserts both faces are loaded and in use. The fallback is Helvetica, then
   Arial, and it is not size-adjusted: a swap reflows the page once. */
@font-face {
  font-family: 'Schibsted Grotesk';
  font-weight: 400 900;
  font-display: swap;
  src: url('./vendor/schibsted-grotesk-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Schibsted Grotesk';
  font-weight: 400 900;
  font-display: swap;
  src: url('./vendor/schibsted-grotesk-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@layer reset {
  *, *::before, *::after { box-sizing: border-box; }
  body, h1, h2, h3, p, ul, ol, dl, dd, figure { margin: 0; }
  ul, ol { padding: 0; list-style: none; }
  img, svg { display: block; max-inline-size: 100%; block-size: auto; }
  button, input { font: inherit; }
}

@layer base {
  :root {
    /* type: 18 px base, a 1.25 ratio, nothing under 14 px */
    --eccm-t-s: 0.875rem;
    --eccm-t-m: 1.125rem;
    --eccm-t-l: 1.4rem;
    --eccm-t-xl: clamp(1.55rem, 1.2rem + 1.5vw, 1.75rem);
    --eccm-t-2xl: clamp(1.85rem, 1.3rem + 2.5vw, 2.2rem);
    --eccm-lh-body: 1.5;
    --eccm-lh-head: 1.15;
    --eccm-lh-meta: 1.4;
    --eccm-measure: 66ch;
    /* space: quarter-rem steps, linear at the bottom, widening at the top */
    --eccm-s-1: 0.25rem;
    --eccm-s-2: 0.5rem;
    --eccm-s-3: 0.75rem;
    --eccm-s-4: 1rem;
    --eccm-s-6: 1.5rem;
    --eccm-s-8: 2rem;
    --eccm-s-12: 3rem;
    --eccm-s-16: 4rem;
    --eccm-s-24: 6rem;
    --eccm-gutter: var(--eccm-s-4);
    /* colour: ink on white, one accent, every pair computed against the ground */
    --eccm-ground: #ffffff;
    --eccm-ink: #1a1a1a;
    --eccm-ink-2: #555555;
    --eccm-rule: #d9d9d9;
    --eccm-rule-strong: #999999;
    --eccm-accent: #b3400f;
    /* the picture column is the thumbnail's own width: eccm.ee makes them 300
       on the long side, so 300 draws eight of the ten at 1:1. The first cut
       had 224, and the picture came out 146 px tall beside text of 170 to
       200, which is the almost-equal that reads as nervous (asked 2026-09-26:
       "image should be bigger to avoid awkward a-bit-longer text. gestalt
       101, just-a-bit-different sizes are nervous"). A typed pixel, because
       it is the size of an object, not a relationship (positron-compose §0) */
    --eccm-pic-w: 300px;
    /* the mark, on a desk. eccm.ee draws it at 381 px */
    --eccm-mark-w: 20rem;
  }
  @media (min-width: 48rem) { :root { --eccm-gutter: var(--eccm-s-8); } }

  html { background: var(--eccm-ground); color: var(--eccm-ink); }
  body {
    font: 400 var(--eccm-t-m) / var(--eccm-lh-body) 'Schibsted Grotesk', Helvetica, Arial, sans-serif;
    text-wrap: pretty;
    /* grayscale antialiasing: on a Mac the default subpixel rendering draws
       Helvetica heavier than a designed site looks, and a lighter page was
       asked for; Windows ignores both lines (asked 2026-09-26: "do you have
       font antialias in positron and in eccm?", and neither did) */
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
  }
  /* headings at text weight: hierarchy is size and space, and bold is spent
     nowhere by default (eccm-ui §2, Vignelli; asked 2026-09-26 as "rough and
     90ies", which system Helvetica in bold is) */
  h1, h2, h3 { font-weight: 400; line-height: var(--eccm-lh-head); text-wrap: balance; }
  a {
    color: inherit;
    text-decoration-line: underline;
    text-decoration-thickness: 1px;
    text-underline-offset: 0.15em;
    text-decoration-color: var(--eccm-rule-strong);
  }
  a:hover { text-decoration-color: var(--eccm-accent); }
  :focus-visible { outline: 2px solid var(--eccm-accent); outline-offset: 2px; }
  [lang="et"] .prose { hyphens: auto; }
  .prose { overflow-wrap: anywhere; max-inline-size: var(--eccm-measure); }
}

@layer layout {
  /* The frame never types a pixel width (the site being replaced types 3,320). */
  .frame { inline-size: min(100% - 2 * var(--eccm-gutter), 72rem); margin-inline: auto; }
  /* the mark and the language switch on one band, then the menu on a band
     ruled top and bottom, which is eccm.ee's own order (flag, logo, rule,
     menu) with its orange rule and its stickiness left out. The head band is
     a row with exactly two ends, the mark and the switch, and the frame gives
     it a width to spread across (positron-compose §6) */
  .site-head { padding-block: var(--eccm-s-6); }
  /* baseline: the mark's box is its ink and its bottom edge is the tagline's
     baseline, so the switch sits on that line (asked 2026-09-26: "et en lang
     position / stylying neds work", when it floated 24 px above the E on the
     JPEG's empty margin) */
  .site-head > .frame { display: flex; justify-content: space-between; align-items: baseline; column-gap: var(--eccm-s-6); }
  /* the menu band is ruled in the logo's own ink, not the hairline grey
     (asked 2026-09-26: "use black on top menu borders to mach with logo") */
  .site-nav { border-block: 1px solid var(--eccm-ink); }
  .site-nav > .frame {
    display: flex; flex-wrap: wrap; align-items: baseline;
    column-gap: var(--eccm-s-6); row-gap: var(--eccm-s-1);
    padding-block: var(--eccm-s-3);
  }
  /* main is the box the list asks about its width (positron-compose §6, a
     component asks its own box, never the window), because the row's shape
     depends on whether 45 ch of text fits beside a 300 px picture */
  main { padding-block: var(--eccm-s-8) var(--eccm-s-16); container-type: inline-size; }
  /* the footer carries no rule above it (asked 2026-09-27: "rm border above
     eccm footer"); the air alone separates it */
  .site-foot {
    padding-block: var(--eccm-s-8) var(--eccm-s-12);
    display: flex; flex-wrap: wrap; gap: var(--eccm-s-2) var(--eccm-s-8);
    font-size: var(--eccm-t-s); line-height: var(--eccm-lh-meta); color: var(--eccm-ink-2);
  }
}

@layer components {
  /* the mark: the SVG redraw at its own proportions, never wider than its frame */
  .mark { display: block; inline-size: min(100%, var(--eccm-mark-w)); }
  .mark img { inline-size: 100%; }

  /* the menu is a start row that wraps as a cluster: every item its own size,
     one gap, nothing past the gutter, no hamburger; the language switch is
     text, up beside the mark where eccm.ee keeps its flag */
  .nav { display: flex; flex-wrap: wrap; column-gap: var(--eccm-s-6); row-gap: var(--eccm-s-1); }
  .nav a, .lang a { text-decoration: none; }
  .nav a:hover, .lang a:hover { text-decoration-line: underline; text-decoration-color: var(--eccm-accent); }
  .nav [aria-current="page"], .lang [aria-current="page"] { text-decoration-line: underline; text-decoration-color: currentColor; text-decoration-thickness: 1px; text-underline-offset: 0.15em; }
  /* the switch: the current language is text and carries the menu's own
     current-page line, the other is a link with no line until hovered, both
     at the menu's size (asked 2026-09-26: "et en underlines do not match
     menu ones") */
  .lang { display: flex; column-gap: var(--eccm-s-3); }

  /* the event list, in eccm.ee's own shape: the picture at the start, the
     title and the facts beside it. The picture is plain, nothing drawn over
     it and no ground under the row (asked 2026-09-26: "i asked just to use
     event images, not overlay anything ... unneccessary backgrounds"). Rows
     are separated by space alone, three steps above the gaps inside a row
     (positron-compose §1, §4; asked 2026-09-26 "it sould be light, airy, good
     type stuff", and start with too much); every title starts on one x
     because the picture column is one width for the whole list */
  .events { display: grid; row-gap: var(--eccm-s-12); max-inline-size: 60rem; }
  .ev {
    display: grid; grid-template-columns: var(--eccm-pic-w) minmax(0, 1fr);
    column-gap: var(--eccm-s-6); align-items: start;
  }
  .ev-pic { display: block; aspect-ratio: 3 / 2; overflow: clip; }
  .ev-pic img { inline-size: 100%; block-size: 100%; object-fit: cover; }
  /* a compound title has no break opportunity at a slash, and eccm.ee's own
     list opens with one: Gestuurid/situatsioonid: is 24 characters that ran
     52 px past the phone's column (MEASURED at 375, 404 px of page in 375),
     so the title gets the same floor the prose has (design plan rule 21) */
  /* no underline under a bold title (asked 2026-09-26: "this thin underline
     under bold title is pathetic design"); the row's shape says it is a link,
     and hover puts a line back for the pointer */
  /* a row's text is three registers with large contrast between them
     (eccm-ui §2, Vignelli's twice): a small muted line first with the date,
     time, venue and category, the title at twice the body in text weight,
     then the summary at body size. Reported 2026-09-26 with a crop of a row
     whose title, date and summary were three sizes a step apart: "it feels
     unprofessiona (yea type size scale but...)" */
  .ev-kicker { display: flex; flex-wrap: wrap; gap: var(--eccm-s-1) var(--eccm-s-4); font-size: var(--eccm-t-s); line-height: var(--eccm-lh-meta); color: var(--eccm-ink-2); font-variant-numeric: tabular-nums; margin-block-end: var(--eccm-s-3); }
  .ev-kicker time + time { margin-inline-start: calc(-1 * var(--eccm-s-2)); }
  .ev-title { font-size: var(--eccm-t-2xl); overflow-wrap: anywhere; }
  .ev-title a { text-decoration-line: none; }
  .ev-title a:hover, .ev-title a:focus-visible { text-decoration-line: underline; }
  /* a step more between the three registers than the first cut had (asked
     2026-09-26 with a crop: "feels like these need biiit more vert space in
     between"): 12 px under the small line, 16 px under the title */
  .ev-summary { margin-block-start: var(--eccm-s-4); }

  /* ── the event page and the edit form, HTML only ─────────────────────────── */
  /* a crumb above a title: the page this one came from, small, in the muted ink */
  .crumb { font-size: var(--eccm-t-s); line-height: var(--eccm-lh-meta); color: var(--eccm-ink-2); margin-block-end: var(--eccm-s-4); }
  /* the head of an event page: the title, the facts and the actions in one
     column and the picture beside them at its own size on a desk, the two
     stacked under 60rem of main. arvopart.ee's page for the same concert uses
     the width this way and the demo did not (compared 2026-09-26) */
  .event-top { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--eccm-s-8); margin-block-end: 2lh; }
  .event-lead h1 { max-inline-size: var(--eccm-measure); margin-block: var(--eccm-s-2) var(--eccm-s-8); }
  /* the facts as label over value, the label small in the muted ink, cells at
     least 14rem so a phone stacks them and a desk pairs them, no rule, no box */
  .facts { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 14rem), 1fr)); gap: var(--eccm-s-6) var(--eccm-s-8); max-inline-size: var(--eccm-measure); }
  .facts > div { display: grid; gap: var(--eccm-s-1); align-content: start; }
  .facts dt { font-size: var(--eccm-t-s); line-height: var(--eccm-lh-meta); color: var(--eccm-ink-2); }
  .facts a + a { margin-inline-start: var(--eccm-s-3); }
  .event-actions { display: flex; flex-wrap: wrap; gap: var(--eccm-s-3); margin-block-start: var(--eccm-s-8); }
  /* the picture at its own size, its shape reserved from its own pixels so
     nothing moves while it arrives */
  .event-pic { max-inline-size: var(--eccm-measure); }
  .event-pic img { inline-size: 100%; aspect-ratio: 900 / 599; object-fit: cover; }
  /* the next events at the foot, so the page does not end in a dead end */
  .next { margin-block-start: var(--eccm-s-16); }
  .next h2 { font-size: var(--eccm-t-l); margin-block-end: var(--eccm-s-6); }
  .next-list { display: grid; gap: var(--eccm-s-4); max-inline-size: var(--eccm-measure); }
  .next-list li { display: grid; grid-template-columns: max-content minmax(0, 1fr); column-gap: var(--eccm-s-6); }
  .next-list time { font-variant-numeric: tabular-nums; color: var(--eccm-ink-2); }
  .next-list a { text-decoration-line: none; }
  .next-list a:hover, .next-list a:focus-visible { text-decoration-line: underline; }
  .next-list small { display: block; font-size: var(--eccm-t-s); line-height: var(--eccm-lh-meta); color: var(--eccm-ink-2); }
  .event-pic figcaption { margin-block-start: var(--eccm-s-2); font-size: var(--eccm-t-s); line-height: var(--eccm-lh-meta); color: var(--eccm-ink-2); }
  /* prose flow: the owl, and the space is counted in the leading, Rutter's
     one line between paragraphs and a heading carrying two above and half a
     line below (eccm-ui §1, Bringhurst 2.2.2). The first cut said one leading
     and set 1em, which is 18 px against a 27 px line; 1lh is the line */
  .flow > * + * { margin-block-start: var(--eccm-flow, 1lh); }
  .flow > h2 { --eccm-flow: 2lh; font-size: var(--eccm-t-l); }
  .flow > h2 + * { --eccm-flow: 0.5lh; }
  /* a label and value list: two columns where the label column costs less
     than a third of the width, label over value where it would not (asked
     2026-09-27 with a phone crop of Loovkommunikatsioon taking half the row) */
  .credits { display: grid; grid-template-columns: max-content minmax(0, 1fr); column-gap: var(--eccm-s-6); row-gap: var(--eccm-s-1); }
  .credits dt { color: var(--eccm-ink-2); }
  .small { font-size: var(--eccm-t-s); line-height: var(--eccm-lh-meta); color: var(--eccm-ink-2); }
  /* a button: a word in a 3rem box ruled in ink, no radius, no shadow, always
     in the system face whatever face the page around it wears (asked
     2026-09-27: "they are kind of system buttons"). Two modes: regular, ruled
     in the ink; inversed, filled. On a page that derives a scheme from its
     picture the button reads that scheme's tokens, with the page's own as the
     fallback, and the inversed one takes the derived accent when there is
     one, with the text colour the derivation says passes on it. 3rem is a
     finger, not a relationship */
  .btn { display: inline-flex; align-items: center; block-size: 3rem; padding-inline: var(--eccm-s-6); border: 1px solid var(--ev-ink, var(--eccm-ink)); background: transparent; color: var(--ev-ink, var(--eccm-ink)); text-decoration: none; cursor: pointer; font-family: 'Schibsted Grotesk', Helvetica, Arial, sans-serif; font-weight: 400; }
  .btn:hover { text-decoration: none; outline: 1px solid var(--ev-ink, var(--eccm-ink)); outline-offset: -2px; }
  .btn-pri { background: var(--ev-accent, var(--ev-ink, var(--eccm-ink))); color: var(--ev-on-accent, var(--ev-ground, var(--eccm-ground))); border-color: transparent; }
  .btn-pri:hover { outline-color: var(--ev-on-accent, var(--ev-ground, var(--eccm-ground))); }
  /* the form: one column at the measure, a visible label above each field,
     fields a finger tall, ruled in the strong hairline, ink on white */
  .note { color: var(--eccm-ink-2); margin-block-end: var(--eccm-s-8); }
  .form { display: grid; gap: var(--eccm-s-6); max-inline-size: var(--eccm-measure); }
  .field { display: grid; gap: var(--eccm-s-1); }
  .field label { font-size: var(--eccm-t-s); line-height: var(--eccm-lh-meta); color: var(--eccm-ink-2); }
  .field-row { display: grid; gap: var(--eccm-s-6); grid-template-columns: repeat(auto-fit, minmax(min(100%, 14rem), 1fr)); }
  .form input, .form select, .form textarea { inline-size: 100%; border: 1px solid var(--eccm-rule-strong); border-radius: 0; background: var(--eccm-ground); color: var(--eccm-ink); padding: var(--eccm-s-3) var(--eccm-s-4); font: inherit; }
  /* a step more air in the fields and the buttons (asked 2026-09-26: "add
     biiit more padding on input fields and buttons"): 3rem tall, 12 by 16 in */
  .form input:not([type="file"]), .form select { block-size: 3rem; }
  .form input[type="file"] { padding: 0; border: 0; }
  /* a native date field: iOS draws it as a tall box with the value centred,
     whatever the padding says (asked 2026-09-27 with a crop: "Date field too
     much padding"); with the appearance off it is a text field like the rest */
  .form input[type="datetime-local"], .form input[type="date"], .form input[type="time"] { appearance: none; -webkit-appearance: none; display: block; text-align: start; }
  .form input[type="datetime-local"]::-webkit-date-and-time-value { text-align: start; min-block-size: 1.5em; }
  .form textarea { line-height: var(--eccm-lh-body); resize: vertical; }
  .hint { font-size: var(--eccm-t-s); line-height: var(--eccm-lh-meta); color: var(--eccm-ink-2); }
  /* the picture field: the current picture and a drop field side by side,
     each at least 14rem, one under the other when the measure cannot hold
     both. The native input covers the whole field at zero opacity, so a drop
     or a click anywhere on it is a drop or a click on the control, with no
     script; the dashed rule is the affordance, solid ink is the hover, and
     the accent ring is the keyboard's (asked 2026-09-26: "do proper file
     styling with drop affodance") */
  .field-name { font-size: var(--eccm-t-s); line-height: var(--eccm-lh-meta); color: var(--eccm-ink-2); }
  .drop { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 14rem), 1fr)); gap: var(--eccm-s-4); }
  .drop img { inline-size: 100%; aspect-ratio: 3 / 2; object-fit: cover; }
  .drop-zone { position: relative; display: grid; place-content: center; gap: var(--eccm-s-3); padding: var(--eccm-s-8); min-block-size: 12rem; text-align: center; border: 1px dashed var(--eccm-rule-strong); cursor: pointer; }
  .drop-zone .drop-say { font-size: var(--eccm-t-m); line-height: var(--eccm-lh-body); }
  .drop-zone .drop-say b { font-weight: 400; }
  .drop-zone .hint { max-inline-size: 26ch; margin-inline: auto; }
  .drop-zone:hover { border: 1px solid var(--eccm-ink); }
  .drop-zone:has(input:focus-visible) { border: 1px solid var(--eccm-ink); outline: 2px solid var(--eccm-accent); outline-offset: 2px; }
  .form .drop-zone input { position: absolute; inset: 0; inline-size: 100%; block-size: 100%; opacity: 0; cursor: pointer; }
  .drop-say { text-wrap: balance; }
  .actions { display: flex; flex-wrap: wrap; gap: var(--eccm-s-3); margin-block-start: var(--eccm-s-4); }
}

@layer page {
  h1 { font-size: var(--eccm-t-2xl); margin-block-end: var(--eccm-s-8); }
  /* the list's heading is a label above the list, small and muted, because
     the titles are the page (arvopart.ee's ghost section label, compared
     2026-09-26); it stays the h1 for the outline */
  h1.list-label { font-size: var(--eccm-t-s); line-height: var(--eccm-lh-meta); color: var(--eccm-ink-2); margin-block-end: var(--eccm-s-6); }
}

/* the phone: the mark at 11rem so the mark and the menu together stay under
   a quarter of the first screen (eccm.ee spends 40 per cent of it). MEASURED
   at 12rem with the switch on a third menu line: 238 px of 812. The row's
   phone shape is the container query above, which the phone also enters */
@media (max-width: 40rem) {
  @layer base { :root { --eccm-mark-w: 11rem; } }
  @layer components {
    /* label over value on a phone: a label column beside a value gives the
       value half the width and wraps a name every four letters (MEASURED on
       an iPhone, 2026-09-27) */
    .credits, .facts, .next-list li { grid-template-columns: minmax(0, 1fr); }
    .credits > div, .facts > div { display: grid; gap: var(--eccm-s-1); }
    .credits { row-gap: var(--eccm-s-3); }
  }
  @layer layout {
    .site-head { padding-block: var(--eccm-s-4); }
    .site-nav > .frame { padding-block: var(--eccm-s-2); }
    main { padding-block: var(--eccm-s-6) var(--eccm-s-16); }
  }
}

/* the compact row: a square thumbnail at the row's start, small enough that
   no 300 px picture is upscaled, the title at body size and bold. Decided by
   the list's own container, not the window: 300 px of picture, a gap and
   45 ch of Helvetica at 18 px is about 47rem, and under that the text column
   would fall below the measure (MEASURED at the harness's 756 px window: 40 ch
   in a 400 px column beside the 300 px picture) */
@container (min-width: 60rem) {
  @layer components {
    .event-top { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--eccm-s-12); align-items: start; }
  }
}

@container (max-width: 47rem) {
  @layer components {
    .events { row-gap: var(--eccm-s-6); }
    .ev { column-gap: var(--eccm-s-4); grid-template-columns: 5.5rem minmax(0, 1fr); }
    .ev-pic { aspect-ratio: 1; }
    .ev-title { font-size: var(--eccm-t-xl); }
  }
}
