/**
 * @file poster.css
 * @description Shared poster and showroom shapes. Views compose these classes and own their layout.
 * @usage Linked immediately after theme.css in spa.html.
 * @version-history
 *   v1.40.0 -- 2026-10-25 -- Library sizes (Jouni): the Status reads --text-2xs (11px, was .66rem, 10.6px); on a touch screen the action link and the tab take the finger in an area 44px high around their words, with no change to their look. Outside the app-catalog ranges.
 *   v1.39.0 -- 2026-10-21 -- .poster-action--control (Action `control`): the action link in a box as tall as the control cut, a touch target. Additive, outside the app-catalog ranges.
 *   v1.38.0 -- 2026-10-06 --.store-soon-ask ("Opens soon" pressed for the discount code, in the control's own shape) and .store-soon-code (the code in an ink frame with its copy button and when to use it). Additive: nothing carries them unless site.store_soon_code is set.
 *   v1.37.0 -- 2026-10-06 -- .store-soon (components/StoreDoor.js): a control into a store that does not take orders yet keeps its shape, does not answer the pointer, and a door loses its link underline; .store-soon-note, the line that says so. Additive: nothing carries the class while site.store_status is "open".
 *   v1.36.0 -- 2026-09-27 -- .poster-aside--chapter (Note aside `chapter`): the old catalogue's detail aside (.mk-aside), for appcat parity (sections-c); additive, outside the app-catalog ranges.
 *   v1.36.0 -- 2026-09-27 -- .poster-chip--need (Mark tone 'need') and .poster-chips--spread (Marks `spread`): the old catalogue's Needs chips, for appcat parity (sections-a); additive, outside the app-catalog ranges.
 *   v1.35.0 -- 2026-09-27 -- .poster-aside--disclosure (Note aside tone 'disclosure'): the old catalogue's AI notice (.dtl-ai-notice), for appcat parity; additive, outside the app-catalog ranges.
 *   v1.34.0 -- 2026-09-27 -- .poster-action--plain (Action tone 'plain'): the old catalogue's grey "▶ toggle", for appcat parity; additive, outside the app-catalog ranges.
 *   v1.33.0 -- 2026-09-27 -- appcat parity: the line tone's grey is the old catalogue's (its --text-dim is the site's --text-muted); the glyph tone on the card ground in regular weight, as the old .icon-pick. Outside the app-catalog ranges.
 *   v1.32.0 -- 2026-09-27 -- .poster-slab-words (Loud mark): the loud action's words after its sign, hidden but spoken under 900px (the old catalogue's "+"), for appcat; additive, outside the app-catalog ranges.
 *   v1.31.0 -- 2026-09-27 -- The tab's line tone (.poster-tab--line: the app catalogue's dialog tabs) and glyph tone (.poster-tab--glyph: a square with one mark, the Add dialog's ready icons), for appcat; additive.
 *   v1.30.0 -- 2026-09-27 -- A count inside the chosen tab takes the tab's own words' colour (it was --on-sun, which a theme that draws the chosen tab on its accent, Pebble, could not read); the action link's pressed tone.
 *   v1.29.0 -- 2026-09-26 -- The shapes are drawn by the components (components/Action.js, Mark.js, Note.js), which pages call with data; .poster-label--block, a label on a line of its own.
 *   v1.28.0 -- 2026-09-26 -- The pill corner stays on the tab and on the action link's tone with a ground (jump), and leaves the action link's underline; a disabled action's line reads --shape-rule-colour and the quiet tone's line --shape-frame (a move: the AIMEAT values equal the old ones).
 *   v1.27.0 -- 2026-09-26 -- The Tag's frame colour reads --shape-frame-colour and its letter spacing --shape-tracking-action (a move: the AIMEAT values equal the old ones).
 *   v1.26.0 -- 2026-09-26 -- The figure written on a meter, .poster-meter-figure: the Wallet meter's figure, taken by the AI budget bars too.
 *   v1.25.0 -- 2026-09-26 -- The Tag's remove mark, .poster-chip-x: grey, coral under the pointer (Jouni's decision "Remove mark").
 *   v1.24.0 -- 2026-09-26 -- The box's raised tone, .poster-box--raised: the heavier frame with the raised shadow for the thing that stands out (Jouni's decision "Box").
 *   v1.23.0 -- 2026-09-26 -- The action link's Settings tones, .poster-action--small, --lower and --row: the size and thinner line of Settings' own way on (Jouni's decision "Action link in Settings").
 *   v1.22.0 -- 2026-09-26 -- The avatar's agent tone, .poster-box--avatar.poster-box--agent (a dashed frame, grey initials), the look Contacts, Notifications, Email and MCP drew alike.
 *   v1.21.0 -- 2026-09-25 -- A count inside the chosen tab keeps dark words on the sun (.poster-tab.is-on .poster-count).
 *   v1.20.0 -- 2026-09-25 -- The icon button's pressed tone, .poster-icon.is-on (ink ground, the mark in the page ground's colour); the first page to wear it is Memory's collection button.
 *   v1.19.0 -- 2026-09-25 -- The tab's attention tone, .poster-tab--attention (the Access filter "unused" keeps its coral).
 *   v1.18.0 -- 2026-09-25 -- The action link's danger tone, .poster-action--danger: coral words and line
 *     for an act that removes or revokes (Jouni's decision "Action link").
 *   v1.17.0 -- 2026-09-25 -- A tab that cannot be chosen is dimmed (.poster-tab:disabled); the menu row's danger tone (.poster-menu-row--danger).
 *   v1.16.0 -- 2026-09-25 -- The tab's filter tone, .poster-tab--filter, in the admin filters' values
 *     (Jouni's decision "Tabs and filters", the admin filter look accepted as a tone).
 *   v1.15.0 -- 2026-09-25 -- The Tag's tones (.poster-chip--sun, --coral, --ink) and a row of tags
 *     (.poster-chips); the Status (.poster-status and its four tones), from the lab's accepted
 *     proposals (Jouni's decisions "Tag" and "Status"); the chip's corner reads the pill corner.
 *   v1.14.0 -- 2026-09-24 -- The shapes read the theme's shape values (theme.css --shape-*): the corners,
 *     frames, shadows and letter case of the slab, the action link and tab, the label, the headings, the
 *     panel, box, frame, record, choice, sticker, icon, menu row and count. The values are today's, so
 *     every page is unchanged (a move); a theme sets them once (07 "New components follow the theme").
 *   v1.13.0 -- 2026-09-24 -- The slab's danger tone, .poster-slab--danger (Jouni's decision "Dialog actions").
 *   v1.12.0 -- 2026-09-24 -- The action link's notice and jump tones (Jouni's decision "Small link").
 *   v1.11.0 -- 2026-09-24 -- The menu row, .poster-menu-row (Jouni's decision "Menu row").
 *   v1.10.0 -- 2026-09-24 -- The tab's tile tone, .poster-tab--tile (Jouni's decision "Choice").
 *   v1.9.0 -- 2026-09-24 -- .poster-icon and its small cut (Jouni's decision "Icon button").
 *   v1.8.0 -- 2026-09-24 -- .poster-action:disabled, dimmed (Jouni's decision "Step button").
 *   v1.7.0 -- 2026-09-23 -- .poster-dialog deleted (Jouni's decision): no page ever put it on markup
 *     outside the rolled-back unification, and the site has its own dialog.
 *   v1.6.0 -- 2026-09-23 -- The pulse two components share (the waiting note's dot and a live
 *     timeline row), moved unchanged from css/parts-steps.css (UI consolidation phase 1, a move).
 *   v1.5.0 -- 2026-09-23 -- The section title's large cut (.poster-section-title--large), moved from the
 *     home's band title with its values (UI consolidation slice 1).
 *   v1.4.0 -- 2026-09-14 -- The choice tile (.poster-choice) and the sun sticker (.poster-sticker).
 *   v1.3.0 -- 2026-09-13 -- Share numeral cuts, record titles and the quota meter role.
 *   v1.2.0 -- 2026-09-13 -- Share recurring initials boxes and the compact, large and irreversible asides.
 *   v1.1.0 -- 2026-09-13 -- V2: source band phone padding and the named coral section shadow cut.
 *   v1.0.0 -- 2026-09-13 -- V0: lift the existing shapes; section titles and panels use the locked B1 design.
 */

/* The slow pulse of something waiting or happening now (components/waiting-note.css,
   components/timeline.css). */
@keyframes poster-pulse { 0%, 100% { opacity: 0.35; } 50% { opacity: 1; } }

/* Profile page title. The two headline sizes are the only per-view shape properties. */
.poster-page-title {
  font-family: var(--font-poster); font-weight: var(--font-poster-weight);
  font-size: var(--poster-page-size, 2.8rem); line-height: var(--font-poster-leading);
  letter-spacing: var(--font-poster-tracking); text-transform: var(--shape-case-heading);
  color: var(--text); margin-bottom: 0.6rem;
}

/* B1: the slab starts a section; the sun edge bounds the selected tab's content. */
.poster-section { margin-top: 4.5rem; }
.poster-section-title {
  font-family: var(--font-poster); font-weight: var(--font-poster-weight);
  font-size: var(--poster-section-size, 1.9rem); line-height: var(--font-poster-leading);
  letter-spacing: var(--font-poster-tracking); text-transform: var(--shape-case-heading);
  background: var(--text); color: var(--bg);
  padding: .55rem 1rem .5rem; border-bottom: 6px solid var(--sun);
  margin: 0 0 1.4rem;
}
/* The large cut: the home's bands (formerly home.css .koti-band-title and surface.css
   .sf-band-title, which carried exactly these values). */
.poster-section-title--large { font-size: 2.4rem; }
@media (max-width: 560px) {
  .poster-section-title--large { font-size: 1.7rem; padding: .45rem .8rem .4rem; }
}
.poster-panel { border-left: 4px solid var(--sun); border-radius: var(--shape-corner); box-shadow: var(--shape-shadow); padding-left: 1.25rem; margin: 0 0 1.5rem; }

/* Lifted from the home's connection row and status lines (formerly home-journey.css and home.css). */
.poster-row { border-block: 1px solid var(--border); padding-block: 1rem; }
.poster-row--thing { border-top: var(--shape-frame-heavy) solid var(--shape-rule-colour); }
.poster-label {
  font-size: var(--text-xs); color: var(--accent); text-transform: var(--shape-case-label);
  letter-spacing: var(--shape-tracking-label); font-weight: var(--weight-heavy); line-height: 1.3;
}
/* A label on a line of its own (components/Mark.js Label `block`). */
.poster-label--block { display: block; }

/* @app-catalog:begin — the app catalog's build (scripts/build-app-catalog.ts) copies every range
   between these markers into its page, so its dialogs draw the action link and the loud action from
   these rules rather than from a copy. The tokens the ranges read are on that script's list. */
/* Lifted from the home's ink-underlined action (formerly home.css .koti-link), including the unselected tab. */
.poster-action, .poster-tab {
  display: inline-flex; align-items: center; gap: .4rem;
  background: none; border: 0; border-bottom: var(--shape-frame-heavy) solid var(--shape-rule-colour);
  padding: 0 0 2px; cursor: pointer;
  font: inherit; font-weight: var(--weight-heavy); font-size: var(--text-body-sm); text-transform: var(--shape-case-action); letter-spacing: var(--shape-tracking-action);
  color: var(--text); text-decoration: none; white-space: nowrap;
}
.poster-action:hover, .poster-tab:hover { border-color: var(--accent); color: var(--accent); }
/* The pill corner belongs to a tab, which a theme may give a ground; the action link's underline has
   none, so a rounded theme does not bend its line. */
.poster-tab { border-radius: var(--shape-corner-pill); }
/* An action that cannot be pressed yet is dimmed and does not answer the pointer (Jouni's decision
   "Step button"; the dimming is the control slab's). */
.poster-action:disabled { opacity: 0.45; cursor: default; border-color: var(--shape-rule-colour); color: var(--text); }
/* @app-catalog:end */
/* The source's later on-sun correction keeps selected words ink in both themes. */
.poster-tab.is-on { background: var(--sun); color: var(--on-sun); text-decoration: none; padding: .2rem .5rem; }
/* A tab that cannot be chosen now (the page is saving, or it counts nothing) is dimmed like the
   action link that cannot be pressed (Jouni's decision "Step button"). */
.poster-tab:disabled { opacity: 0.45; cursor: default; }
/* A count inside a tab is the Count (.poster-count, tally); inside the chosen tab it keeps dark
   words on the sun, as the tab's own words do. The Count has no frame, so only its words change. */
.poster-tab.is-on .poster-count { color: inherit; }
/* The action link's Settings tones (Jouni's decision "Action link in Settings"): the size and the
   thinner line the Settings pages' own way on had (formerly .og-door, organism-controls.css). small:
   in a page head or a section; lower: a softer way on ("Show 13 more", "Copy ref"; formerly
   .og-door--quiet), with small; row: the same at the end of a dense row, with small. They come
   before the other tones, which set their own size and line. */
.poster-action--small { border-bottom-width: var(--shape-frame); padding: 0 0 1px; font-family: var(--font-showroom-body); font-size: .8rem; }
.poster-action--lower { text-transform: none; letter-spacing: 0; font-size: .88rem; }
.poster-action--lower.copied { color: var(--success-fg); border-color: var(--success-fg); }
.poster-action--row { font-size: .72rem; }
/* On a touch screen the action link and the tab keep their look, and an area 44px high around the
   words takes the finger (the dialog footer's rule, dialog.css, for every action link and tab;
   Jouni: library sizes, 2026-10-25). A mouse keeps the exact area of the words. */
@media (pointer: coarse) {
  .poster-action, .poster-tab { position: relative; }
  .poster-action::after, .poster-tab::after { content: ''; position: absolute; left: 0; right: 0; top: 50%; height: max(100%, 44px); transform: translateY(-50%); }
}
/* The action link's tones (Jouni's decision "Action link"): the looks he kept, each in its own
   values, so one component carries every quiet way on. A tone sets back what the base above sets
   and the look does not have. more: "Show all" under a list (formerly .poster-fold); quiet: the
   chat's side column actions (formerly .poster-rail-action's look); back: the back link (formerly
   .poster-back's look); text: a plain word under a chat message (Listen, Copy; formerly .btn-ghost). */
.poster-action--more {
  display: inline-block; padding: .2rem 0; border: 0;
  font-family: var(--font-mono); font-weight: var(--weight-regular); font-size: var(--text-small); line-height: normal; text-transform: none; letter-spacing: normal;
  color: var(--accent); text-decoration: underline; text-underline-offset: 4px; white-space: normal;
}
.poster-action--more:hover { color: var(--text); }
.poster-action--quiet { border-bottom-width: var(--shape-frame); padding: 0 0 1px; font-family: var(--font-showroom-body); font-size: .78rem; line-height: normal; white-space: normal; }
.poster-action--quiet.copied { color: var(--success-fg); border-color: var(--success-fg); }
.poster-action--back {
  display: inline-block; padding: 0; border: 0;
  font-family: var(--font-mono); font-weight: var(--weight-regular); font-size: var(--text-note); text-transform: none; letter-spacing: normal;
  color: var(--accent); white-space: normal;
}
.poster-action--back:hover { color: var(--text); }
.poster-action--text { padding: 0 6px; border: 0; gap: .35rem; font-family: var(--font-body); font-weight: var(--weight-medium); font-size: .7rem; line-height: normal; text-transform: none; letter-spacing: normal; color: var(--text-dim); }
.poster-action--text:hover { color: var(--text); }
.poster-action--text.copied { color: var(--success-fg); }
/* plain (Action tone 'plain', appcat): a grey word in the page's own letters with no line, the old
   catalogue's "▶ toggle" over its Active Extensions strip (its --text-muted, the theme's --muted). */
.poster-action--plain { display: inline-block; padding: 0; border: 0; font-family: inherit; font-weight: 400; font-size: .8rem; line-height: normal; text-transform: none; letter-spacing: normal; color: var(--muted); }
.poster-action--plain:hover { color: var(--muted); }
/* danger: an act that removes or revokes (Settings' delete, revoke and reset links; formerly
   .og-door--danger and the coral .btn-danger words): coral words and a coral line; under the pointer
   the same as the action link's own hover. A difference that carries meaning stays a tone. */
.poster-action--danger { color: var(--accent); border-bottom-color: var(--accent); }
.poster-action--danger:hover { color: var(--accent); border-color: var(--accent); }
/* An action that stays pressed while what it started runs (Listen while it reads): the pale coral
   ground main's .inbox-speak-btn--on drew (components/Action.js `pressed`). */
.poster-action.is-on { background: var(--accent-subtle); border-color: var(--accent-border); color: var(--accent); }
/* Two small links Jouni kept as they look (decision "Small link"), each in the values it had with the
   classic button it wore, hover included. notice: "What does that mean?" under the AI notice
   (formerly .btn-ghost with .poster-ai-notice-more); jump: the jump to the latest message (formerly
   .btn-outline with .poster-conversation-jump, a small ink block). */
.poster-action--notice {
  gap: 0.35rem; padding: 0; border: 0; border-radius: var(--radius-sm);
  font-family: var(--font-mono); font-weight: var(--weight-regular); font-size: 0.7rem; line-height: normal;
  text-transform: none; letter-spacing: normal; white-space: normal;
  color: var(--accent); text-decoration: underline; text-underline-offset: 3px; transition: all 0.15s;
}
.poster-action--notice:hover { color: var(--text); background: var(--control-bg); }
.poster-action--jump {
  display: inline-block; padding: 6px 12px; border: 0; border-radius: var(--shape-corner-pill); background: var(--text); color: var(--bg); box-shadow: 4px 4px 0 var(--sun);
  font-family: var(--font); font-weight: var(--weight-heavy); font-size: 0.74rem; line-height: normal;
  text-transform: uppercase; letter-spacing: 0.04em; white-space: normal; transition: all 0.15s;
}
.poster-action--jump:hover { color: var(--text); background: var(--control-bg); box-shadow: var(--shadow-sm); transform: none; }
/* The tab's fold tone (Jouni's decision "Tabs and filters"): the home's switch ("Recent", "Mine";
   formerly .poster-fold), coral typewriter words underlined; the chosen one is on the sun by
   .poster-tab.is-on above. */
.poster-tab--fold {
  display: inline-block; padding: .2rem 0; border: 0;
  font-family: var(--font-mono); font-weight: var(--weight-regular); font-size: var(--text-small); line-height: normal; text-transform: none; letter-spacing: normal;
  color: var(--accent); text-decoration: underline; text-underline-offset: 4px; white-space: normal;
}
.poster-tab--fold:hover { color: var(--text); }
/* The tab's tile tone (Jouni's decision "Choice": the background pattern tiles kept as they look;
   formerly .poster-settings-pattern-choice): framed tiles on the card ground, the chosen one on the
   sun, a solid ink shadow under the pointer. It sets back what the tab's base sets and the tile does
   not have (the underline, the capitals, the line height a button has by default). */
.poster-tab--tile {
  display: inline-block; background: var(--card-bg); border: var(--shape-frame) solid var(--shape-rule-colour); color: var(--text);
  padding: 0.35rem 0.7rem; font-family: var(--font-showroom-body); font-size: var(--text-small); font-weight: var(--weight-bold);
  line-height: normal; text-transform: none; letter-spacing: normal; white-space: normal;
}
.poster-tab--tile:hover { border-color: var(--text); color: var(--text); box-shadow: 3px 3px 0 var(--text); }
.poster-tab--tile.is-on { background: var(--sun); color: var(--on-sun); padding: 0.35rem 0.7rem; box-shadow: 3px 3px 0 var(--text); }
/* The tab's filter tone (Jouni's decision "Tabs and filters": the admin filters kept as they look;
   the values of admin-hooks.css .adm-hook-fchip): small typewriter words in a grey frame with no
   ground, frame and words turning ink under the pointer; the chosen one on the sun in an ink frame.
   It sets back what the tab's base sets and the filter does not have. */
.poster-tab--filter {
  padding: 3px 9px; background: none; border: var(--shape-frame) solid var(--border); border-radius: var(--shape-corner-control);
  font-family: var(--font-mono); font-size: .72rem; font-weight: var(--weight-medium); line-height: normal; text-transform: none; letter-spacing: normal;
  color: var(--text-dim);
}
.poster-tab--filter:hover { border-color: var(--text); color: var(--text); }
.poster-tab--filter.is-on { border-color: var(--text); background: var(--sun); color: var(--on-sun); padding: 3px 9px; }
/* The tab's attention tone: a filter whose items need the person (Access, "unused" keys), coral in
   frame and words while it is not chosen, as its coral chip was (formerly access-poster.css). */
.poster-tab--attention:not(.is-on) { border-color: var(--accent); color: var(--accent); }
/* The tab's line tone (components/Tabs.js tone 'line'): the app catalogue's dialog tabs (Paste / File;
   the old page's .modal-tab), small capitals with no ground, grey until chosen; the chosen one is ink
   over a coral line. It sets back the ground and the padding the chosen tab has. */
.poster-tab--line {
  padding: 0 0 2px; background: transparent; border: 0; border-bottom: var(--shape-frame-heavy) solid transparent;
  font-family: var(--font-body); font-weight: var(--weight-heavy); font-size: .78rem; letter-spacing: .04em;
  text-transform: var(--shape-case-action); color: var(--text-muted);
}
.poster-tab--line:hover { color: var(--text); border-color: transparent; background: transparent; }
.poster-tab--line.is-on { background: transparent; color: var(--text); padding: 0 0 2px; border-bottom-color: var(--accent); }
/* The tab's glyph tone (Tabs tone 'glyph'): a square holding one mark, in a thin grey frame on the
   card ground, ink-framed on the sun under the pointer and when chosen: a row of ready icons to pick
   from (the app catalogue's Add dialog, the old page's .icon-pick). */
.poster-tab--glyph {
  display: inline-flex; align-items: center; justify-content: center; box-sizing: border-box;
  width: 36px; height: 36px; padding: 0; background: var(--card-bg); border: var(--shape-frame) solid var(--border);
  border-radius: var(--shape-corner-control); font-size: 1.1rem; font-weight: var(--weight-regular); line-height: normal; text-transform: none; letter-spacing: 0;
}
.poster-tab--glyph:hover, .poster-tab--glyph.is-on { border-color: var(--text); background: var(--sun); color: var(--on-sun); padding: 0; }

/* @app-catalog:begin */
/* The profile slab and the home's large door are the two cuts named in brief 10.3. */
.poster-slab {
  background: var(--text); color: var(--bg);
  border: 0; border-radius: var(--shape-corner-pill); box-shadow: var(--shape-shadow-action);
  padding: 10px 16px;
  font-family: var(--font-showroom-body); font-weight: var(--font-poster-strong-weight); font-size: var(--text-small);
  text-transform: var(--shape-case-action); letter-spacing: var(--shape-tracking-action); text-decoration: none; cursor: pointer;
  transition: transform 120ms ease, box-shadow 120ms ease;
}
.poster-slab:hover { transform: translate(2px, 2px); box-shadow: var(--shape-shadow-action-pressed); color: var(--sun); }
/* A copy made from a slab says so in green for a moment (the values .btn-primary.copied gave it
   while slabs also wore .btn-primary). */
.poster-slab.copied, .poster-slab.success { background: var(--success-gradient); box-shadow: var(--success-glow); }
.poster-slab--large { padding: 1.2rem 1.7rem; font-size: 1.02rem; font-weight: var(--weight-heavy); box-shadow: 8px 8px 0 var(--sun); }
.poster-slab--large:hover { box-shadow: 4px 4px 0 var(--sun); }
/* The control cut: a 44px button in a row of controls (the chat's New conversation and Send,
   formerly chat.css .chat-new/.chat-send, which carried the base's values and these). */
.poster-slab--control {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 44px; padding: 0 16px;
  font-family: inherit; font-weight: var(--weight-heavy); cursor: pointer;
}
.poster-slab--control:disabled { opacity: 0.45; cursor: default; transform: none; }
/* The slab's danger tone (Jouni's decision "Dialog actions"): an action that cannot be undone, coral
   with an ink shadow, in the values the dialog's footer gave .btn-danger-solid. */
.poster-slab--danger { background: var(--accent); color: #fff; box-shadow: 4px 4px 0 var(--text); }
.poster-slab--danger:hover { color: #fff; box-shadow: 2px 2px 0 var(--text); }
/* @app-catalog:end */
/* The loud action's words after its sign (Loud mark, appcat): on a phone the sign alone stands and
   the words stay for a screen reader (the old catalogue's "+ Create an app", 44px square). */
@media (max-width: 900px) {
  .poster-slab:has(> .poster-slab-words) { min-width: 44px; min-height: 44px; padding: 0 12px; }
  .poster-slab-words { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
}

/* The icon button (Jouni's decision "Icon button"): a button that is a mark, not a word. One square
   in a thin ink frame, the sun under the pointer; 44px is the composer's control size, the small cut
   is the size of the dialog's close square. A disabled one is dimmed like the control slab. */
.poster-icon {
  display: inline-flex; align-items: center; justify-content: center; box-sizing: border-box;
  width: 44px; height: 44px; padding: 0; border: var(--shape-frame) solid var(--shape-rule-colour); border-radius: var(--shape-corner-control); box-shadow: none;
  background: var(--bg); color: var(--text); font: inherit; font-size: var(--text-md); line-height: 1; cursor: pointer;
}
.poster-icon:hover { background: var(--sun); color: var(--on-sun); }
.poster-icon:disabled { opacity: 0.45; cursor: default; background: var(--bg); color: var(--text); }
.poster-icon--small { width: 28px; height: 28px; font-size: var(--text-note); }
/* The pressed tone: an icon button that stays pressed while what it adds is in (a key in the
   collection), ink ground with the page ground's colour for the mark, a chosen tab's contrast. */
.poster-icon.is-on { background: var(--text); color: var(--bg); }

/* The menu row (Jouni's decision "Menu row"): one choice in an opened menu, as the prompt card's
   rows are drawn (formerly .btn-ghost with .poster-prompt-menu-item, whose values these are): plain
   words on a quiet ground, a thin line between rows. The menu around it is a column, which
   stretches the rows to its width. */
.poster-menu-row {
  display: inline-flex; align-items: center; gap: 0.35rem;
  padding: 0.55rem 0.85rem; border: 1px solid var(--control-border); border-radius: var(--shape-corner-control);
  background: var(--control-bg); color: var(--text-dim); text-align: left; text-decoration: none;
  font-size: var(--text-note); font-weight: var(--weight-medium); line-height: normal; transition: all 0.15s;
}
.poster-menu-row:hover { border-color: var(--text-muted); color: var(--text); background: var(--control-bg); }
.poster-menu-row + .poster-menu-row { border-top-color: var(--border); }
/* A row that removes something keeps the danger colour it had in Settings' menus (a meaning, not a style). */
.poster-menu-row--danger, .poster-menu-row--danger:hover { color: var(--danger-fg); }

/* Boxes carry the object; dimensions, grids and placement belong to the view. */
.poster-box, .poster-box.poster-box--avatar { border: var(--shape-frame) solid var(--shape-frame-colour); }
.poster-box { background: var(--card-bg); padding: 1rem; margin-block: 1rem; border-radius: var(--shape-corner); box-shadow: var(--shape-shadow); }
/* The box's tones (Jouni's decision "Object box", every look kept): copy, a text a person copies,
   on the grey ground with its parts padding themselves (the prompt card); row, one result in a list,
   with small padding (the chat's result card, whose kind edge is its own). */
.poster-box--copy { background: var(--bg-dim); padding: 0; overflow: hidden; }
/* raised (Jouni's decision "Box"): the thing that stands out, a row you opened or the way to take
   first, in the heavier frame with the raised shadow (formerly the lead roads' own rules, the
   opened row's .poster-frame and the opened panels' own frames). */
.poster-box--raised { border-width: var(--shape-frame-heavy); box-shadow: var(--shape-shadow-raised); }
.poster-box--row { background: var(--bg-card); padding: 8px 10px; }
.poster-box.poster-box--avatar {
  display: flex; align-items: center; justify-content: center; box-sizing: border-box;
  padding: 0; margin: 0; background: transparent;
  font-family: var(--font-poster); font-weight: var(--font-poster-weight); font-size: var(--text-body);
  color: var(--text);
}
.poster-box--avatar.poster-box--small { font-size: var(--text-note); }
/* The avatar's agent tone: the mark of a sender that is not a person (an agent, an app, a mail
   service not yet connected, a tool that is gone), a dashed frame and grey initials (formerly
   contacts-poster.css .ct-av--agent, notifications and email .nt-av.ct-av--agent, mcp .mc-av--dash). */
.poster-box--avatar.poster-box--agent { border-style: dashed; color: var(--text-dim); }
.poster-box--meter { margin: 0; padding: 0; background: var(--bg); }
.poster-box--meter rect { fill: var(--sun); shape-rendering: crispEdges; }
.poster-box--meter.poster-box--quota { background: var(--card); }
.poster-box--quota rect { fill: var(--accent); transition: width .3s; }
.poster-box--quota.is-full rect { fill: var(--danger); }
/* The figure written on a meter (the Wallet meter's, formerly morsel-flow.css .wal-bar span): small
   typewriter figures in ink at the meter's left edge; the meter places it and sets its line height. */
.poster-meter-figure { position: absolute; left: .5rem; top: 0; font-family: var(--font-mono); font-size: .72rem; color: var(--text); }
.poster-frame { border: var(--shape-frame-heavy) solid var(--shape-frame-colour); border-radius: var(--shape-corner); box-shadow: var(--shape-shadow); background: var(--card); }
.poster-record { padding: 1.2rem 1.4rem; border: var(--shape-frame-heavy) solid var(--shape-frame-colour); border-radius: var(--shape-corner); box-shadow: var(--shape-shadow-raised); background: var(--card); }
/* A choice tile: one of a few boxed answers, the chosen one on the sun with an ink shadow
   (scheduler-poster.css .sc-choice is the source cut). A sticker: a small sun-ground box with a
   short headline and one door, for the one fact about a thing that must be seen before its name
   is read (the agent's access level, design canvas "Your Agents" header B). */
.poster-choice { padding: .7rem .8rem; border: var(--shape-frame) solid var(--shape-rule-colour); border-radius: var(--shape-corner-control); background: var(--card-bg); cursor: pointer; text-align: left; font-family: var(--font-showroom-body); font-size: var(--text-small); line-height: 1.45; color: var(--text-dim); }
.poster-choice b { display: block; font-weight: var(--weight-heavy); font-size: .88rem; color: var(--text); margin-bottom: .2rem; }
.poster-choice:hover { border-color: var(--accent); }
.poster-choice.on { background: var(--sun); color: var(--on-sun); box-shadow: var(--shape-shadow-chosen); }
.poster-choice.on b { color: var(--on-sun); }
.poster-sticker { display: flex; flex-direction: column; align-items: flex-end; gap: .35rem; background: var(--sun); color: var(--on-sun); border: var(--shape-frame) solid var(--shape-frame-colour); border-radius: var(--shape-corner); padding: .6rem .9rem; box-shadow: 4px 4px 0 var(--text); }
.poster-sticker .poster-stat-number { color: var(--on-sun); margin: 0; white-space: nowrap; }
.poster-sticker .poster-action, .poster-sticker .og-door { color: var(--on-sun); border-bottom-color: var(--on-sun); font-size: .74rem; }
.poster-sticker .poster-action:hover, .poster-sticker .og-door:hover { color: var(--text); }
/* profile-poster.css has no coral aside. The existing .ld-sh-box supplies this shape. */
.poster-aside {
  padding: 1rem 1.25rem; border: 3px dashed var(--accent); border-radius: var(--shape-corner-control); background: var(--card-bg);
  font-family: var(--font-showroom-body); font-size: var(--text-body); line-height: 1.6; color: var(--text);
}
.poster-aside--small { padding: .9rem 1.1rem; font-family: inherit; font-size: var(--text-base); line-height: 1.55; color: inherit; }
.poster-aside--large { padding: 1.25rem 1.5rem; font-size: inherit; line-height: inherit; color: inherit; }
.poster-aside--irreversible { border-style: solid; }
/* The aside's tones (Jouni's decision "Attention note", every look kept): waiting, the next move is
   in another window (the waiting note, a thin dashed ink frame on grey); suggestion, a line the
   person can wave away (the phone nudge, a thin dashed ink frame, small bold words). */
.poster-aside--waiting { padding: .9rem 1rem; border: 2px dashed var(--text); background: var(--bg-dim); font-family: inherit; font-size: inherit; line-height: inherit; color: inherit; }
.poster-aside--suggestion { padding: 8px 12px; border: 2px dashed var(--text); background: none; font-family: inherit; font-size: var(--text-sm); font-weight: var(--weight-semibold); line-height: 1.5; color: inherit; }
/* disclosure (appcat): a statement of what a panel is, as the law asks it said before the first
   exchange (EU AI Act Art. 50(1)): a thin frame with a coral bar at its start, small grey words, the
   bold ones in ink (the old app catalogue's .dtl-ai-notice). */
.poster-aside--disclosure { margin: 0 0 10px; padding: 8px 10px; border: 1px solid var(--border); border-left: var(--shape-frame-heavy) solid var(--accent); border-radius: var(--shape-corner); background: none; font-size: .82rem; line-height: 1.4; color: var(--text-dim); overflow-wrap: anywhere; }
.poster-aside--disclosure :is(b, strong) { color: var(--text); }
/* chapter (appcat): the aside of a chapter of the old app catalogue's detail (.mk-aside: "This is on
   the record", a legal page's readiness): a little less room inside, 22px of air above, 14px below. */
.poster-aside.poster-aside--chapter { margin: 22px 0 14px; padding: 14px 18px; }
/* The Tag (Jouni's decision "Tag", 2026-09-23): one small framed word in the typewriter face that names
   a kind, a version, a role or a relation, in four tones: plain names a thing; sun is the chosen one
   or the one that counts now; coral is the one to notice; ink is the one that belongs to you. */
.poster-chip {
  display: inline-block; padding: .1rem .45rem; border: 1px solid var(--shape-frame-colour); border-radius: var(--shape-corner-pill);
  font-family: var(--font-mono); font-size: var(--text-2xs); font-weight: var(--weight-medium); letter-spacing: var(--shape-tracking-action);
  color: var(--text); background: transparent;
}
.poster-chip--sun { background: var(--sun); color: var(--on-sun); }
.poster-chip--coral { border-color: var(--accent); color: var(--accent); }
.poster-chip--ink { background: var(--text); color: var(--card-bg); }
/* dim: a tag that counts nothing yet (no workspaces, no rights), grey frame and words, as main's
   .og-chip--dim drew it. */
.poster-chip--dim { border-color: var(--border); color: var(--text-dim); }
/* need (appcat): a thing an app needs to run, a cortex it loads or an extension it calls, in the ink
   frame on the card ground (the old app catalogue's Needs chips, .dtl-chip in .dtl-chips). */
.poster-chip--need { display: inline-flex; align-items: center; gap: 6px; padding: 2px 8px; border-color: var(--text); border-radius: var(--shape-corner); background: var(--card-bg); font-size: 12px; font-weight: 500; letter-spacing: normal; color: var(--text); }
/* A row of tags. */
.poster-chips { display: flex; flex-wrap: wrap; gap: .4rem; align-items: center; }
/* A row of tags set further apart (Marks `spread`, appcat): the old catalogue's .dtl-chips. */
.poster-chips.poster-chips--spread { gap: 8px; align-items: normal; }
/* The remove mark (Jouni's decision "Remove mark", 2026-09-26): the ✗ after a tag's name that takes a
   tag or a member off, grey until the pointer is on it, then coral. The name stays the strongest thing
   in the tag, and a row of tags does not read as a row of warnings. */
.poster-chip-x { background: none; border: 0; padding: 0 0 0 .3rem; margin: 0; cursor: pointer; font: inherit; line-height: 1; color: var(--text-dim); }
.poster-chip-x:hover { color: var(--accent); }
/* The Status (Jouni's decision "Status", 2026-09-23): one small word in capitals on a pale colour that
   says a state; a fill, never a frame, so it stays apart from a tag in the same row. */
.poster-status {
  display: inline-block; padding: 1px 7px; border-radius: var(--shape-corner-pill);
  font-family: var(--font-mono); font-size: var(--text-2xs); font-weight: var(--weight-medium); text-transform: var(--shape-case-label);
}
.poster-status--fine { background: var(--success-bg); color: var(--success-fg); }
.poster-status--attention { background: var(--warn-bg); color: var(--warn-fg); }
.poster-status--danger { background: var(--danger-bg); color: var(--danger-fg); }
.poster-status--off { background: var(--bg-surface); color: var(--text-dim); }
.poster-crumb { font-family: var(--font-mono); font-weight: var(--weight-regular); font-size: var(--text-small); letter-spacing: 0; text-transform: none; color: var(--accent); }
.poster-crumb::after { content: ' /'; }
/* A small number (Jouni's decision "Count"): on coral when something waits for the person, without a
   ground when it only says how many. The values are the profile menu's count (.pf-side-badge); the
   small cut is the bell's size, for a count that sits on an icon. */
.poster-count { display: inline-block; padding: .05rem .45rem; border-radius: var(--shape-corner-pill); font-family: var(--font-mono); font-size: .7rem; font-weight: var(--weight-medium); letter-spacing: 0; }
.poster-count--waiting { background: var(--accent); color: var(--bg); }
.poster-count--tally { background: none; color: var(--text-dim); }
.poster-count--small { font-size: .6rem; padding: 0 3px; }
/* When a thing happened: small grey typewriter letters, the chat's cut (Jouni's decision "Timestamp"). */
.poster-time { font-family: var(--font-mono); font-size: var(--text-2xs); color: var(--text-dim); }
.poster-stat {
  display: flex; align-items: baseline; gap: 1rem; margin: 0; padding: .8rem 0;
  border-top: 3px solid var(--text); color: var(--text); text-decoration: none; font-size: var(--text-md-plus); font-weight: var(--weight-heavy);
}
.poster-stat:hover { color: var(--accent); }
.poster-stat-number {
  font-family: var(--font-poster); font-weight: var(--font-poster-weight);
  font-size: 3rem; line-height: var(--font-poster-leading); letter-spacing: var(--font-poster-tracking);
  color: var(--text); margin-right: .6rem;
}
.poster-stat-number--small { font-size: var(--text-xl); line-height: 1; letter-spacing: normal; }
.poster-stat-number--large { font-size: 3.4rem; }
.poster-stat-number--step { color: var(--accent); }
.poster-stat-number--band { color: var(--bg); }
.poster-record-title {
  margin: 0; font-family: var(--font-poster); font-weight: var(--font-poster-weight);
  font-size: 1.9rem; line-height: 1.05; letter-spacing: var(--font-poster-tracking);
  text-transform: uppercase; color: var(--text);
}
.poster-record-title--small { font-size: 1.8rem; line-height: var(--font-poster-leading); }
/* The numeral's phone cut, from the home's big numeral at 560px (formerly home.css .koti-big). */
@media (max-width: 560px) {
  .poster-stat-number:where(:not(.poster-stat-number--small)) { font-size: 2.2rem; }
}

/* Showroom: .ld-sh-trust, .ld-sh-room, .ld-sh-door and .ld-sh-btn.
   The sun band lives in landing.css (.ld-band--sun), not landing-showroom.css. */
.showroom-band { padding: 3.5rem 3rem; background: var(--text); color: var(--bg); }
@media (max-width: 600px) { .showroom-band { padding: 2rem 1.25rem; } }
.showroom-band--sun { padding: 3rem; background: var(--sun); color: var(--on-sun); border-bottom: 3px solid var(--text); }
.showroom-section { padding: 1.75rem; background: var(--card-bg); border: 3px solid var(--text); box-shadow: 8px 8px 0 var(--sun); }
/* The design skill names sun, coral and ink shadows; the source rooms use the first two. */
.showroom-section--coral { box-shadow: 8px 8px 0 var(--accent); }
.showroom-door { font-family: var(--font-showroom-body); font-size: var(--text-body); font-weight: var(--weight-heavy); color: var(--text); text-decoration: none; border-bottom: 3px solid var(--accent); }
.showroom-door:hover { color: var(--accent); }
.showroom-slab {
  display: inline-block; font-family: var(--font-showroom); text-transform: uppercase; font-size: var(--text-md);
  padding: 1rem 1.75rem; border: 3px solid var(--text); box-shadow: 6px 6px 0 var(--text);
  text-decoration: none; transition: transform 120ms ease, box-shadow 120ms ease; text-align: center;
}
.showroom-slab:hover { transform: translate(2px, 2px); box-shadow: 3px 3px 0 var(--text); }
.showroom-slab--hot { background: var(--accent); color: #fff; }
.showroom-slab--sun { background: var(--sun); color: var(--on-sun); }
.showroom-slab--ink { background: var(--text); color: var(--bg); box-shadow: 6px 6px 0 var(--accent); }
/* A control into a store that is not open yet (components/StoreDoor.js): the same shape, words that
   say "Opens soon", and nothing to press. A door drops the underline that marks it as a link. */
.store-soon { cursor: default; pointer-events: none; }
.showroom-door.store-soon { border-bottom-color: transparent; }
.store-soon-note { font-weight: var(--weight-heavy); }
/* With a discount code set, "Opens soon" is pressed for the code (.store-soon-ask keeps the control's
   own shape), and the code then stands in its place in an ink frame, ready to copy. */
.store-soon-ask { cursor: pointer; }
.store-soon-code {
  display: inline-flex; flex-wrap: wrap; align-items: center; gap: 0.5rem 0.75rem; max-width: 100%;
  padding: 0.75rem 1rem; border: var(--shape-frame-heavy) solid var(--text); background: var(--card-bg); color: var(--text);
}
.store-soon-code-value { font-family: var(--font-mono); font-size: var(--text-md); letter-spacing: 0.05em; }
.store-soon-code-hint { flex-basis: 100%; color: var(--text-muted); }
.showroom-slab--ink:hover { box-shadow: 3px 3px 0 var(--accent); }
/* The action link at the control size (Action `control`): the same word and line, standing in a box
   as tall as the control cut (44px), so a finger can press it on a phone. The words sit at the foot
   of the box, so the line stays under them. */
.poster-action--control { display: inline-flex; align-items: flex-end; min-height: 44px; }
