/* ============================================================
   CROW Make — loaded after styles.css on make.html only.
   Form controls, the card-key screens, the editor, and pop-ups.
   Buttons, link-style buttons, pixel toggles, tokens and the sidebar
   layout come from styles.css.
   ============================================================ */

/* ── form controls ───────────────────────────────────────── */
/* every field is a pixel box: a 2px orange outline with stepped corners
   (the shared corner shape in styles.css, plus one pixel inside each
   corner to join the steps). Lime on hover. The type-ahead suggestion
   list is one too, floating just under its box, and so is a long list to
   tick from (.scroll-list). */
/* a box's own settings stay on that box: the pop-up's 4px steps, outline
   and fill mustn't pass down to the tick boxes and fields inside it */
@property --box-px { syntax: "*"; inherits: false; }
@property --box-line { syntax: "*"; inherits: false; }
@property --field-fill { syntax: "*"; inherits: false; }
.make :is(input[type="text"], input[type="url"], input[type="email"], input[type="search"], textarea, input[type="checkbox"], input[type="radio"], .suggest-list, .scroll-list, .place-pill),
.popup,   /* (on any page: the card page's fork pop-up too) */
.make .info-tip::before {   /* (the "i"'s backdrop; a pseudo-element can't go inside :is()) */
  --px: var(--box-px, 2px);                       /* a box can set bigger steps (the pop-up: 4px) */
  --field-line: var(--box-line, var(--accent));   /* …and its own outline color (the pop-up's) */
  --field-corners:
    linear-gradient(var(--field-line) 0 0) left var(--px) top var(--px) / var(--px) var(--px) no-repeat,
    linear-gradient(var(--field-line) 0 0) right var(--px) top var(--px) / var(--px) var(--px) no-repeat,
    linear-gradient(var(--field-line) 0 0) left var(--px) bottom var(--px) / var(--px) var(--px) no-repeat,
    linear-gradient(var(--field-line) 0 0) right var(--px) bottom var(--px) / var(--px) var(--px) no-repeat;
  border: var(--px) solid var(--field-line);
  border-radius: 0;
  background: var(--field-corners), var(--field-fill, transparent);
  background-origin: border-box;
}
.make :is(input, textarea):hover { --field-line: var(--lime); }

/* text boxes, links, filters, dropdowns and notes: the strong orange tint
   inside while typing */
.make :is(input[type="text"], input[type="url"], input[type="email"], input[type="search"], textarea) {
  display: block;
  width: 100%;
  padding: 0.5rem 0.75rem;
  color: var(--ink);
  font-size: var(--fs-s);
}
.make textarea { resize: vertical; font-family: inherit; line-height: 1.5; }
.make :is(input[type="text"], input[type="url"], input[type="email"], input[type="search"], textarea):focus-visible {
  outline: none;
  --field-line: var(--accent);
  --field-fill: var(--tint-strong);
}

/* lists to pick from (dropdowns, and type-ahead boxes you can browse): a
   small pixel arrow at the right, drawn as three rows of pixels */
.make .suggest-browse input[type="text"] {
  --field-arrow:
    linear-gradient(var(--field-line) 0 0) right 0.75rem top calc(50% - 3px) / 10px 2px no-repeat,
    linear-gradient(var(--field-line) 0 0) right calc(0.75rem + 2px) top calc(50% - 1px) / 6px 2px no-repeat,
    linear-gradient(var(--field-line) 0 0) right calc(0.75rem + 4px) top calc(50% + 1px) / 2px 2px no-repeat;
  padding-right: 2.25rem;
  background: var(--field-arrow), var(--field-corners), var(--field-fill, transparent);
  background-origin: border-box;
}

/* tick boxes and radio buttons: small pixel boxes (--tick, 8 pixels of
   2px). A ticked checkbox fills orange with a dark pixel X; a chosen radio
   keeps its outline, with an orange square dot in the middle. */
.make { --tick: 16px; }
.make :is(input[type="checkbox"], input[type="radio"]) {
  appearance: none;
  flex: none;
  width: var(--tick);
  height: var(--tick);
  margin: 0;
  /* in a list row: centered on the first line of its label (--first-line, set on .choice below) */
  margin-top: calc((var(--first-line, var(--tick)) - var(--tick)) / 2);
  cursor: pointer;
}
/* keyboard focus on a tick box: a dark ring around its whole row (a ring
   on the small box itself would be cut off by its pixel corners) */
.make :is(input[type="checkbox"], input[type="radio"]):focus-visible { outline: none; }
:is(.choice, .check):has(> input:focus-visible) { outline: 2px solid var(--ink); outline-offset: 2px; }
.make input[type="checkbox"]:checked {
  --field-line: var(--accent);
  --field-fill: var(--accent);
  background:   /* the X, pixel by pixel (x, y from the box's outer corner) */
    linear-gradient(var(--ink-on-color) 0 0) 4px 4px / 2px 2px no-repeat,
    linear-gradient(var(--ink-on-color) 0 0) 6px 6px / 2px 2px no-repeat,
    linear-gradient(var(--ink-on-color) 0 0) 8px 8px / 2px 2px no-repeat,
    linear-gradient(var(--ink-on-color) 0 0) 10px 10px / 2px 2px no-repeat,
    linear-gradient(var(--ink-on-color) 0 0) 10px 4px / 2px 2px no-repeat,
    linear-gradient(var(--ink-on-color) 0 0) 8px 6px / 2px 2px no-repeat,
    linear-gradient(var(--ink-on-color) 0 0) 6px 8px / 2px 2px no-repeat,
    linear-gradient(var(--ink-on-color) 0 0) 4px 10px / 2px 2px no-repeat,
    var(--field-corners), var(--field-fill, transparent);
  background-origin: border-box;
}
.make input[type="radio"]:checked {
  background: linear-gradient(var(--accent) 0 0) center / 6px 6px no-repeat, var(--field-corners);
  background-origin: border-box;
}

/* a chosen row is tinted, so long lists show at a glance what's picked.
   (Rows reach slightly past the text on both sides, for the tint.) */
.choice:has(> input:checked) { background: var(--tint); }

/* a checkbox with its label text beside it */
.check {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin: 0.75rem 0;
  cursor: pointer;
}

.form-error {
  color: var(--error);
  font-size: var(--fs-m);
}

.screen-loading { color: var(--gray); }

/* ── form fields (Basics and later modules) ──────────────── */
.fields { margin: 1.5rem 0 2rem; }
.field { margin-bottom: 1.5rem; }
.field > :is(label, legend, p).mono-u { display: block; margin-bottom: 0.4rem; padding: 0; }
/* gray hint text: field hints and option descriptions (one rule) */
.field-hint,
.choice-desc { color: var(--gray); font-size: var(--fs-s); }
.field-hint { margin: 0 0 0.5rem; }   /* same size as option descriptions */

fieldset.field { margin-inline: 0; padding: 0; border: 0; }
.legend-clear { margin-left: 0.9rem; font-size: 0.85em; }   /* a radio list's "Clear", beside its legend */

/* radio and checkbox rows: the box, then a name over a short description */
.choice {
  --first-line: calc(var(--fs-m) * 1.5);   /* height of the label's first line (a bold name) */
  display: flex;
  align-items: flex-start;
  gap: 0.6rem;
  margin-inline: -0.5rem;
  padding: 0.35rem 0.5rem;
}
/* the box is centered on the first line of its label, however many lines
   follow (see the tick box rule); --first-line is that line's height */
.choice:has(.choice-name:only-child),
.choice-compact { --first-line: calc(var(--fs-s) * 1.5); }   /* a plain name, no description */
.choice-sub :is(.choice, .choice:has(.choice-name:only-child)) { --first-line: calc(var(--fs-xs) * 1.5); }   /* follow-up radios */
.choice label { cursor: pointer; }
.choice-name { display: block; font-size: var(--fs-m); font-weight: 700; }
.choice-name:only-child { font-size: var(--fs-s); font-weight: 400; }   /* a name with no description under it, e.g. a rule */
.choice-desc { display: block; }
/* a small lime chip (js/dom.js chip): after an option's name ("Suggested",
   from your values), under it as a flag ("Has saved content"), or in a
   sentence that mentions one. Dark text so it reads in both modes. */
.chip {   /* shape: the shared pill in styles.css */
  background: var(--lime);
  color: var(--ink-on-color);
  vertical-align: 0.1em;
}
/* the quiet one ("Also fits"): a lime outline, no fill */
.chip-quiet { background: transparent; color: inherit; box-shadow: inset 0 0 0 2px var(--lime); }
.choice-name .chip { margin-left: 0.5em; }
.choice-flag { display: block; width: fit-content; margin-top: 0.3rem; }
/* a chip's reasons ("Because you value …"), each with a lime pixel bullet */
.choice-badge-note {
  position: relative;
  display: block;
  margin: 0.2rem 0 0;
  padding-left: 1em;
}
.choice-badge-note::before {
  content: "";
  position: absolute;
  left: 0;
  top: calc(0.5lh - 0.2em);
  width: 0.45em;
  height: 0.45em;
  background: var(--lime);
  box-shadow: 0 0 0 1px var(--ink-on-color);
}

/* a follow-up choice under a ticked option (choices "sub"), e.g. a rule's
   "Allowed / Not allowed": a row of small radios, indented under the name */
.choice-sub { margin: 0.3rem 0 0.2rem; padding: 0; border: 0; }
.choice-sub .choice { padding-block: 0; }
:is(.choice-sub, .scale) :is(.choice, .choice:has(> input:checked)) { background: none; }   /* scales: the dot is enough; sub-choices: already in a tinted row */
.choice-sub .choice-name { font-size: var(--fs-xs); font-weight: 400; }

.module-picker { margin-block: 1rem 1.5rem; }
.module-picker .choice { padding-block: 0.6rem; border-bottom: var(--rule); }
.module-picker .choice:last-child { border-bottom: 0; }

/* keyword and value tags: small mono chips, each with an × */
.tags {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: 0.4rem;
  margin: 0 0 0.6rem;
}
.tags:empty { display: none; }

.tag {   /* shape: the shared pill in styles.css */
  background: var(--accent);
  color: var(--ink-on-color);
}

/* "More like this / Try something new" (js/controls/alike.js): a row of
   pills to add, gray like an unselected choice, lime on hover */
.alike { display: grid; gap: 0.4rem; margin: 0.25rem 0 0.75rem; }
.alike-row { gap: 0.4rem; }
.alike-row > .summary-label { margin-right: 0.25rem; }
.tag-add { position: relative; border: 0; cursor: pointer; }   /* (its reason hangs from it in the shared bubble) */
.tag-add:is(:hover, :focus-visible):not(:disabled) { background: var(--lime); color: var(--ink-on-color); }
.tag-add:disabled { color: var(--gray); cursor: not-allowed; }
.alike > .field-hint { margin: 0; }

/* a tag's remove button: the same pixel X as rows and the pop-up, small */
.tag-remove {
  display: grid;
  place-items: center;
  width: 1.1em;
  aspect-ratio: 1;
  color: inherit;
}
.tag-remove span { --dot: 2px; }
.tag-remove:hover,
.tag-remove:focus-visible { background: var(--ink); color: var(--lime); }

/* choices as a row of buttons (choices.js layout "buttons"): gray, lime
   on hover, orange when chosen, with stepped corners (shared rule in
   styles.css). The real box is hidden but still takes the keyboard (the
   row gets the focus ring). An option's description shows in a small box
   under it on hover or keyboard focus. */
.choice-buttons { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.choice-buttons > .choice.choice-button { position: relative; margin: 0; padding: 0; background: none; }
.make input.choice-button-input { position: absolute; width: 1px; height: 1px; margin: 0; opacity: 0; }
.choice-button > label {
  --px: 2px;
  display: inline-block;
  padding: 0.35rem 0.9rem;
  background: var(--line);
  color: var(--ink);
  font-size: var(--fs-s);
  cursor: pointer;
}
.choice-button > label:hover { background: var(--lime); color: var(--ink-on-color); }
.choice-button:has(> input:checked) > label { background: var(--accent); color: var(--ink-on-color); }
.choice-tip {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  z-index: 6;
  display: none;
  width: max-content;
  max-width: 18rem;
  padding: 0.4rem 0.6rem;
  background: var(--ink);
  color: var(--bg);
  font-size: var(--fs-xs);
  line-height: 1.4;
  pointer-events: none;
}
.choice:is(.choice-button, .choice-range):is(:hover, :has(> input:focus-visible)) > .choice-tip { display: block; }
/* anything else with a bubble (the card's icons, tool tags, protocol, a scale's target): shown on hover or keyboard focus */
.tip-host { position: relative; cursor: help; }
.tip-host:is(:hover, :focus-visible) > .choice-tip { display: block; }
/* …and it shows it's there: black text turns orange; a gray tag or a lime tile turns orange */
.tip-host:is(:hover, :focus-visible) { color: var(--accent); }
:is(.tag, .card-tile).tip-host:is(:hover, :focus-visible) { background: var(--accent); color: var(--ink-on-color); }

/* picked items as tags (js/controls/picklist.js): click the name to
   annotate it; lime while hovered. A tag with a note or step gets a small
   pixel asterisk badge on its top-right corner (a dark square with a lime
   5x5 asterisk). Tags that can be put in order can be dragged. */
.tag-open {
  color: inherit;
  font: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
}
.pick-tags .tag:has(> .tag-open:is(:hover, :focus-visible)) { background: var(--lime); }
.pick-tags .tag { position: relative; }
.pick-tags .tag[draggable="true"] { cursor: grab; }
.pick-tags .tag.is-dragging { opacity: 0.4; }
/* a tag with a note badge gets room to its right, and a list with any
   badges more room between its rows, so badges don't crowd their
   neighbors (tags keep one height: they don't stretch to fill a row) */
.tag.has-note { margin-right: 0.4rem; }
.tags:has(> .has-note) { row-gap: 0.7rem; }   /* (no extra space above: tags already sit far enough below the text for the badge) */
.note-mark { --px: 2px; position: absolute; top: -7px; right: -7px; width: 14px; height: 14px; padding: 0; border: 0; background: var(--ink-on-color); cursor: pointer; }   /* stepped corners: shared rule in styles.css */
.note-mark:is(:hover, :focus-visible) { background: var(--accent); }
.note-mark::after {
  --dot: 2px;
  content: "";
  position: absolute;
  top: 6px;
  left: 6px;
  width: var(--dot);
  height: var(--dot);
  background: var(--lime);
  box-shadow:
    0 calc(var(--dot) * -2) var(--lime),
    calc(var(--dot) * -2) calc(var(--dot) * -1) var(--lime), 0 calc(var(--dot) * -1) var(--lime), calc(var(--dot) * 2) calc(var(--dot) * -1) var(--lime),
    calc(var(--dot) * -1) 0 var(--lime), var(--dot) 0 var(--lime),
    calc(var(--dot) * -2) var(--dot) var(--lime), 0 var(--dot) var(--lime), calc(var(--dot) * 2) var(--dot) var(--lime),
    0 calc(var(--dot) * 2) var(--lime);
}
.pick-chosen .tags { margin-top: 0.5rem; }
.choice-hint-below { margin: 0.5rem 0 0; }
/* "opens a new tab": a small pixel arrow pointing up and right, in the text's color */
.icon-out { position: relative; display: inline-block; width: 10px; height: 10px; margin-left: 0.4em; vertical-align: 0.05em; }
.icon-out::after {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  width: 2px;
  height: 2px;
  box-shadow: 4px 0, 6px 0, 8px 0, 6px 2px, 8px 2px, 4px 4px, 8px 4px, 2px 6px, 0 8px;
  color: currentColor;
}
.publish-up-to-date { font-weight: 700; }
.publish-history { margin-top: 0.75rem; }
.publish-history li .link-button { margin-left: 0.5rem; }
.publish-wipe { margin: 0.75rem 0 0; }
.publish-history > .summary-label { margin: 0 0 0.25rem; }
.publish-history li + li { margin-top: 0.15rem; }
.pick-chosen.summary { margin-bottom: 1rem; }
.pick-chosen.summary > :is(p, .tags):last-child { margin-bottom: 0; }
.pick-chosen.summary:has(+ .alike:not([hidden])) { margin-bottom: 0.6rem; }
.tab-panel > .fields:first-child { margin-top: 0; }   /* the panel's own padding is gap enough */
/* a term that changes with the open tab (Processes' hint): lime, like the open tab's text */
.tab-term { padding: 0 0.2em; background: var(--lime); color: var(--ink-on-color); }
/* steps (conflict, the ladder; and the card's flows): a gray pixel arrow in the gap between two steps */
:is(.pick-gap.has-arrow, .flow-arrow)::after {
  --dot: 2px;
  content: "";
  position: absolute;
  top: calc(50% - 1px);
  left: calc(50% - 1px);
  width: var(--dot);
  height: var(--dot);
  background: var(--gray);
  box-shadow:
    calc(var(--dot) * -3) 0 var(--gray), calc(var(--dot) * -2) 0 var(--gray), calc(var(--dot) * -1) 0 var(--gray),
    var(--dot) 0 var(--gray), 0 calc(var(--dot) * -1) var(--gray), 0 var(--dot) var(--gray),
    calc(var(--dot) * -1) calc(var(--dot) * -2) var(--gray), calc(var(--dot) * -1) calc(var(--dot) * 2) var(--gray);
}
/* steps (picklist.js staged): one column per step, its name on top, tags
   stacked (several on a step = in parallel); a gap before each and after
   the last to drop a tag into a new step. While dragging, the places to
   drop show a dotted outline, lime under the pointer. */
.pick-tags.in-stages { flex-wrap: wrap; align-items: stretch; gap: 0.75rem 0; }
.pick-step { display: flex; align-items: stretch; }
.pick-stage { display: flex; flex-direction: column; gap: 0.4rem; min-width: 9rem; padding: 0.5rem; }
.pick-stage .summary-label { margin: 0; }
.pick-stage .tags { flex-direction: column; align-items: flex-start; margin: 0; }
.pick-gap { position: relative; width: 1.75rem; }
.pick-gap:last-child { width: 3rem; }
.is-dragging-over :is(.pick-stage, .pick-gap) { outline: 2px dotted var(--line); outline-offset: -2px; }
:is(.pick-stage, .pick-gap).is-over { background: var(--lime); outline-color: var(--accent); }

/* compact rows (js/controls/choices.js layout "compact"): the name, with a
   pixel plus that opens its description underneath */
.choice-compact { flex-wrap: wrap; padding-block: 0.2rem; border-bottom: var(--rule); font-size: var(--fs-s); }
.choice-compact:last-child { border-bottom: 0; }
.choice-compact .choice-name { flex: 1; font-size: inherit; font-weight: 400; }
.choice-about { flex-basis: 100%; padding-left: calc(var(--tick) + 0.6rem); color: var(--gray); }
.choice-about p { margin: 0 0 0.4rem; }

/* a long list (values, approaches): a filter box over a compact scrolling list */
/* group tabs on top of a list (choices.js groups): room above and below,
   slimmer tabs than a tab box's, the open group's description in small gray */
.choice-groups { margin: 1.25rem 0 0.75rem; }
.choice-groups .tab { padding: 0.45rem 0.75rem; }
.choice-group-hint { margin: 0.6rem 0 0; font-size: var(--fs-xs); }
.scroll-list {   /* outline and corners: the pixel box rule at the top */
  max-height: 22rem;
  overflow-y: auto;
  margin-top: 0.5rem;
  padding: 0.25rem 0.75rem;
}

.conflict-notes .callout { margin: 0.75rem 0; }
/* changes, one per line, each after a pixel plus or minus */
.change-list { margin: 0.25rem 0 0.75rem; }
.change-list .pixel-plus,
.change-list .pixel-minus { width: 0.6em; height: 0.6em; vertical-align: 0.05em; }

.callout-small { margin: 0.25rem 0 0.75rem; padding-block: 0.5rem; }   /* a one-line callout inside a field */
.choices + .field { margin-top: 1.25rem; }   /* a pick list's chosen rows, under the list */

/* suggestion field (js/controls/suggest.js): matches drop down under the box */
.suggest { position: relative; }
.suggest-list {   /* outline and corners: the pixel box rule above */
  --field-fill: var(--bg);   /* opaque, over the page */
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  right: 0;
  z-index: 4;
  max-height: 16rem;
  overflow-y: auto;
  margin: 0;
  padding: 0.25rem 0;
  font-size: var(--fs-s);
}
.suggest-list li { padding: 0.4rem 0.75rem; cursor: pointer; }
.suggest-list li:hover { background: var(--tint-strong); }
/* the highlighted suggestion (arrow keys, or the first match): orange, like
   the current page in the header; Enter picks it */
.suggest-list li[aria-selected="true"] { background: var(--accent); color: var(--ink-on-color); }
.suggest-list li[aria-selected="true"] .suggest-note { color: inherit; }
/* small gray text (one rule for all of it): option notes, summary labels,
   a chip's reasons, the original wording of a rule, the card's ID */
.suggest-note,
.choice-badge-note,
.summary-label,
.rule-original,
.editor-card :is(.mono, .mono-u) { color: var(--gray); font-size: var(--fs-xs); }
/* …and small gray mono text: the save status and the sidebar's notes */
.save-status,
.editor-forget-note { color: var(--gray); font-family: var(--mono); font-size: var(--fs-xs); }

/* rows of things side by side that wrap onto more lines when there isn't
   room (one rule for all of them; each sets its own gap) */
.alike-row, .setup-next, #setup-finish, .button-row,
.card-group { display: flex; flex-wrap: wrap; align-items: center; }
/* …and rows that stay on one line */
.field-label { display: flex; align-items: center; }

/* choices in a row: 1–5 scales, yes / no, costs (what 1 and 5 mean go below) */
.scale { display: flex; flex-wrap: wrap; gap: 0.25rem clamp(0.75rem, 2vw, 1.25rem); }
.scale .choice { margin-inline: 0; padding: 0.2rem 0; }
/* a numbered range (1–5, 1–7: scaleField with ends): spread across the
   line, each number under its radio button; what an end (or the middle)
   means shows in the bubble on hover, like the "i" */
.scale-range { justify-content: space-between; }
.choice-range { --first-line: var(--tick); position: relative; flex-direction: column; align-items: center; gap: 0.2rem; }
.choice-range > label { font-size: var(--fs-s); cursor: pointer; }
.choice-range:has(> .choice-tip) > label { text-decoration: underline dotted var(--gray); text-underline-offset: 3px; }
/* (the bubble hangs from its number: the first three's open to the right,
   the last three's to the left, the middle of seven's centered; narrower on
   small screens, so none runs off the edge) */
.choice-range > .choice-tip { max-width: min(18rem, 60vw); }
.choice-range:nth-last-child(-n + 3):not(:nth-child(-n + 3)) > .choice-tip { left: auto; right: 0; }
.choice-range:nth-child(4):nth-last-child(4) > .choice-tip { left: 50%; transform: translateX(-50%); }
.target-scale { margin-bottom: 1.5rem; }

/* a scale's trade-offs, in a note (callout) under it: small mono capitals,
   the low end on the left and the high end on the right (under the
   range's ends); + what you gain, − what it costs (mirrored on the right) */
.trade-offs { margin: 0.75rem 0 0; }
.trade-offs > .summary-label { margin: 0 0 0.4rem; }
.trade-offs-ends { display: grid; grid-template-columns: 1fr 1fr; gap: 0.5rem 1.5rem; font-size: var(--fs-xs); font-weight: 400; line-height: 1.45; }
.trade-offs-ends :is(p, ul) { margin: 0; }
.trade-offs-ends p { margin-bottom: 0.25rem; color: var(--accent); font-weight: 600; }
.trade-offs-end:last-child { text-align: right; }
.trade-offs-ends li::before { width: auto; height: auto; top: 0; background: none; font-weight: 600; }
.trade-offs-ends .gain::before { content: "+"; }
.trade-offs-ends .cost::before { content: "−"; }
.trade-offs-end:last-child li { padding: 0 1em 0 0; }
.trade-offs-end:last-child li::before { left: auto; right: 0; }

/* a choice that can't be selected now (e.g. values, once 5 are) */
.choice:has(> input:disabled) > label { color: var(--gray); cursor: not-allowed; }
.make :is(input[type="checkbox"], input[type="radio"]):disabled { --box-line: var(--line); cursor: not-allowed; }

/* set-up's blocks: a Next under each, and what's still needed beside it */
.setup-next, #setup-finish { gap: 0.25rem 1rem; }
.setup-next > p, #setup-finish > p { margin: 0; }
/* set-up starting from a link (basics.js): only the question and the link show, until it's filled in:
   not the rest of the block (its Next too), nor the blocks after it, even with "Show all fields at once" */
.is-starting > :not(.setup-start),
.is-starting ~ *,
[data-screen="setup"]:has(.is-starting) :is(#setup-modules-block, #setup-finish) { display: none; }

/* repeatable rows (js/controls/rows.js): each entry in a thin box, with a
   pixel × in its corner to remove it */
.rows { display: grid; gap: 0.75rem; margin-bottom: 0.5rem; }
/* blocks drawn on a layer behind them, with stepped pixel corners: rows
   (an orange tint) and summaries — Basics, Rules, the structure in
   Processes — (a lime pixel outline). Being a layer, the corners
   (clip-path, styles.css) don't also clip a dropdown opening inside. */
:is(.row, .summary) {
  --px: 4px;
  position: relative;
  isolation: isolate;
}
:is(.row, .summary)::before { content: ""; position: absolute; inset: 0; z-index: -1; }
.row::before { background: var(--tint); }
/* a summary: a thin (2px) lime outline on the tint, with bigger corners —
   two 2px steps each, so they show on a large box without a heavy line
   (--summary-line and --summary-fill change them, e.g. the card's modules) */
.summary::before {
  --s: 2px;   /* one pixel */
  border: var(--s) solid var(--summary-line, var(--lime));
  background:   /* the two corner steps' inner pixels, then the tint */
    linear-gradient(var(--summary-line, var(--lime)) 0 0) left calc(var(--s) * 2) top var(--s) / var(--s) var(--s) no-repeat,
    linear-gradient(var(--summary-line, var(--lime)) 0 0) left var(--s) top calc(var(--s) * 2) / var(--s) var(--s) no-repeat,
    linear-gradient(var(--summary-line, var(--lime)) 0 0) right calc(var(--s) * 2) top var(--s) / var(--s) var(--s) no-repeat,
    linear-gradient(var(--summary-line, var(--lime)) 0 0) right var(--s) top calc(var(--s) * 2) / var(--s) var(--s) no-repeat,
    linear-gradient(var(--summary-line, var(--lime)) 0 0) left calc(var(--s) * 2) bottom var(--s) / var(--s) var(--s) no-repeat,
    linear-gradient(var(--summary-line, var(--lime)) 0 0) left var(--s) bottom calc(var(--s) * 2) / var(--s) var(--s) no-repeat,
    linear-gradient(var(--summary-line, var(--lime)) 0 0) right calc(var(--s) * 2) bottom var(--s) / var(--s) var(--s) no-repeat,
    linear-gradient(var(--summary-line, var(--lime)) 0 0) right var(--s) bottom calc(var(--s) * 2) / var(--s) var(--s) no-repeat,
    var(--summary-fill, var(--tint));
  background-origin: border-box;
  clip-path: polygon(
    0 calc(var(--s) * 3), var(--s) calc(var(--s) * 3), var(--s) calc(var(--s) * 2), calc(var(--s) * 2) calc(var(--s) * 2),
    calc(var(--s) * 2) var(--s), calc(var(--s) * 3) var(--s), calc(var(--s) * 3) 0,
    calc(100% - var(--s) * 3) 0, calc(100% - var(--s) * 3) var(--s), calc(100% - var(--s) * 2) var(--s),
    calc(100% - var(--s) * 2) calc(var(--s) * 2), calc(100% - var(--s)) calc(var(--s) * 2), calc(100% - var(--s)) calc(var(--s) * 3), 100% calc(var(--s) * 3),
    100% calc(100% - var(--s) * 3), calc(100% - var(--s)) calc(100% - var(--s) * 3), calc(100% - var(--s)) calc(100% - var(--s) * 2),
    calc(100% - var(--s) * 2) calc(100% - var(--s) * 2), calc(100% - var(--s) * 2) calc(100% - var(--s)), calc(100% - var(--s) * 3) calc(100% - var(--s)), calc(100% - var(--s) * 3) 100%,
    calc(var(--s) * 3) 100%, calc(var(--s) * 3) calc(100% - var(--s)), calc(var(--s) * 2) calc(100% - var(--s)),
    calc(var(--s) * 2) calc(100% - var(--s) * 2), var(--s) calc(100% - var(--s) * 2), var(--s) calc(100% - var(--s) * 3), 0 calc(100% - var(--s) * 3));
}
.row { padding: 0.9rem 2.75rem 0.1rem 0.9rem; }   /* room on the right for the × */
.summary { padding: 1rem 1.1rem; }
/* the dotted summary: an outline of square gray pixel dots, like the card's
   section lines, for what's been chosen (pick lists' tags). Each edge is a
   row of 2px dots, 4px apart; the stepped corners come from the clip-path. */
.summary-dotted::before {
  --dots: repeating-linear-gradient(90deg, var(--gray) 0 2px, transparent 2px 6px);
  --dots-down: repeating-linear-gradient(180deg, var(--gray) 0 2px, transparent 2px 6px);
  border: 0;
  background:
    var(--dots) top / 100% 2px no-repeat,
    var(--dots) bottom / 100% 2px no-repeat,
    var(--dots-down) left / 2px 100% no-repeat,
    var(--dots-down) right / 2px 100% no-repeat,
    var(--tint);
}
.summary > :last-child { margin-bottom: 0; }
.row:focus-within { z-index: 1; }   /* the row being edited sits above the next, so its dropdown shows */
.row .field { margin-bottom: 0.9rem; }
.row-remove {
  position: absolute;
  top: 0.5rem;
  right: 0.5rem;
  display: grid;
  place-items: center;
  width: 1.75rem;
  aspect-ratio: 1;
}
.row-remove span { --dot: 3px; color: var(--gray); }
.row-remove:hover span,
.row-remove:focus-visible span { color: var(--error); }
.rows-add { margin: 0.5rem 0 0; }
/* ↑ / ↓ beside the ×, for rows that can be put in order */
.row:has(.row-moves) { padding-right: 6.5rem; }
.row-moves {
  position: absolute;
  top: 0.5rem;
  right: 2.4rem;
  display: flex;
}
/* ↑ / ↓ as pixel arrows: three rows of pixels, like the dropdown arrow */
.row-move {
  width: 1.75rem;
  aspect-ratio: 1;
  color: var(--gray);
  background:
    linear-gradient(currentColor 0 0) center calc(50% - 2px) / var(--w1) 2px no-repeat,
    linear-gradient(currentColor 0 0) center 50% / 6px 2px no-repeat,
    linear-gradient(currentColor 0 0) center calc(50% + 2px) / var(--w3) 2px no-repeat;
}
.row-move[data-dir="up"]   { --w1: 2px;  --w3: 10px; }
.row-move[data-dir="down"] { --w1: 10px; --w3: 2px; }
.row-move:hover,
.row-move:focus-visible { color: var(--accent); }
/* a row folded into one line (rows.js summarize): its summary, Edit, and
   the ✓ that folds it (a pixel tick, beside the ×) */
.row.is-folded { padding-block: 0.6rem; }
.row-summary { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.25rem 1rem; margin: 0; font-size: var(--fs-s); }
.row-summary-text { flex: 1; }
.row-done { position: absolute; top: 0.5rem; right: 2.4rem; }

/* small pixel-icon buttons (the ✓ for done); gray, orange on hover. The ✓
   is drawn with box-shadow pixels, like the × */
.icon-button {
  display: inline-grid;
  place-items: center;
  width: 1.75rem;
  aspect-ratio: 1;
  color: var(--gray);
  vertical-align: middle;
}
.icon-button:is(:hover, :focus-visible) { color: var(--accent); }
/* the ✓: 3px pixels on the same 5x5 grid as the × */
.pixel-tick {
  --dot: 3px;
  width: var(--dot);
  height: var(--dot);
  translate: 0 calc(var(--dot) / -2);   /* the tick sits a half-pixel low on the grid */
  box-shadow:
    calc(var(--dot) * 2) calc(var(--dot) * -1) currentColor, var(--dot) 0 currentColor,
    calc(var(--dot) * -2) var(--dot) currentColor, 0 var(--dot) currentColor, calc(var(--dot) * -1) calc(var(--dot) * 2) currentColor;
}

/* a module's title and lede, with room beside them for edit buttons */
.module-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 1rem; }
.module-head-tools > .link-button { font-size: var(--fs-xs); }
.module-head .module-head-tools:empty { display: none; }
.module-head .lede-small { margin-bottom: 0; }
.module-head + .module-head { margin-bottom: 1.5em; }
.module-head-tools .inline-edit { flex-basis: 100%; }
.inline-edit { display: flex; align-items: flex-start; gap: 0.5rem; width: 100%; }
.inline-edit .field { flex: 1; margin-bottom: 0.5rem; }
.module-head:has(.inline-edit:not([hidden])) .module-head-tools { flex: 1 1 100%; }

.row:has(.row-done:not([hidden])) { padding-right: 4.5rem; }
.row:has(.row-done) .row-moves { right: 4.3rem; }
.row:has(.row-done):has(.row-moves) { padding-right: 8.5rem; }
/* narrow screens: the buttons (↑ ↓ ✓ ×) sit in a strip along the row's top
   instead of a column down its right side, so the fields get the full width */
@media (width < 64rem) {   /* = --narrow */
  .row:has(.row-moves, .row-done:not([hidden])) { padding-top: 2.6rem; padding-right: 0.9rem; }
}

/* for actions that remove things (e.g. "Delete this module") */
.link-button-danger { color: var(--error); text-decoration-color: var(--error); }
.link-button-danger:is(:hover, :focus-visible) { background: var(--error); color: var(--lime); }

/* collapsible sections (js/controls/fold.js): the heading is the toggle
   (its look: styles.css, shared with the docs' sections) */
:is(.fold, .fold-head) > :is(h2, h3) { margin: 0.9em 0 0.25em; }
/* groups inside a section (level 3): smaller, sans, closer together */
:is(.fold-3, .fold-3 > .fold-head) > h3 { margin: 0.4em 0 0; font-family: var(--sans); font-size: var(--fs-m); font-weight: 700; }
.fold-3 > .fold-body { padding: 0.25rem 0 0.75rem calc(9px + 0.35em); }
.fold-body { padding-top: 0.25rem; }
/* a heading with small actions beside it (fold.js actions) */
.fold-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.25rem 1rem; }
.fold-actions { display: flex; gap: 1rem; }
.fold-actions .link-button { font-size: var(--fs-xs); }

/* something that appears in response to an answer (js/reveal.js): shown
   under a layer of pixels that drop away */
.revealing { position: relative; }
.reveal-layer { position: absolute; inset: 0; z-index: 5; width: 100%; height: 100%; pointer-events: none; image-rendering: pixelated; }
/* the cascade: each part fades and slides up, 120ms after the one before */
.cascade-in > * { animation: cascade-in 0.5s ease-out both; animation-delay: calc(var(--i, 0) * 120ms); }
@keyframes cascade-in { from { opacity: 0; translate: 0 0.75rem; } }


/* Basics as a summary: label / answer rows, then the next steps */
.summary-list {
  display: grid;
  grid-template-columns: minmax(6rem, max-content) 1fr;
  gap: 0.5rem 1.5rem;
  align-items: baseline;
  margin: 1rem 0 1.5rem;
}
.summary-list dd { margin: 0; font-size: var(--fs-s); }
/* choices as a table (choices.js choiceTable, e.g. costs): the question on
   the left, the answers as buttons (the shared button choices above), each
   as wide as its word; every row has the same answers, so the columns line
   up. When the table itself is too narrow for the buttons (a container
   query, not the screen size: e.g. a phone): compact radio buttons under
   angled column headings. */
.choice-table-box { container-type: inline-size; }
.cost-values { margin: 0.25rem 0 0.5rem; }
.cost-values li + li { margin-top: 0.1rem; }
.choice-table { width: 100%; border-collapse: collapse; margin: 0.25rem 0 0; }
.choice-table thead { display: none; }
.choice-table tbody th { width: 100%; padding: 0.45rem 1.25rem 0.45rem 0; font-size: var(--fs-s); font-weight: 400; text-align: left; vertical-align: middle; }
.choice-table tbody td { padding: 0.45rem 0.25rem; text-align: center; vertical-align: middle; white-space: nowrap; }
.choice-table tbody tr + tr :is(th, td) { border-top: var(--rule); }
.choice-table .choice-button > label { padding-inline: 0.8rem; }
.choice-table td.choice-guide { padding-right: 0.5rem; text-align: right; }   /* a row's guide (choiceTable row.guide), just before its answers */
.choice-table .choice-button-none:has(> input:checked) > label { background: var(--tint-strong); color: var(--ink); }   /* "Not sure" = no answer: muted, not orange */
@container (width < 34rem) {   /* (about the width the buttons need) */
  .choice-table thead { display: table-header-group; }
  /* the headings, tilted so each column stays narrow */
  /* (each heading sits outside the column's width, so all the answer columns are the same narrow width) */
  .choice-table thead th { position: relative; width: 2.1rem; height: 5.5rem; padding: 0; font-family: var(--mono); font-size: var(--fs-xs); font-weight: 600; color: var(--gray); text-transform: uppercase; letter-spacing: var(--caps-spacing); white-space: nowrap; }
  .choice-table thead th > span { position: absolute; left: 50%; bottom: 0.4rem; transform: rotate(-60deg); transform-origin: left bottom; }
  .choice-table { width: calc(100% - 1.75rem); }   /* (room on the right for the last heading's tilt) */
  .choice-table tbody td { padding-inline: 0.35rem; }
  .choice-table td.choice-guide { width: 6.5rem; white-space: normal; line-height: 1.3; }   /* (a row's guide wraps, leaving room for its name) */
  /* the answers as the shared pixel radio buttons; their words are said by the headings (and each radio's own label) */
  .make .choice-table .choice-button-input { position: static; width: var(--tick); height: var(--tick); opacity: 1; vertical-align: middle; }
  .choice-table .choice-button > :is(label, .choice-tip) { display: none !important; }
}

/* fields as rows (e.g. Locations, Publish's contact): the labels (with
   their "i") in one column as wide as the longest, each lined up with its
   field; anything chosen sits above the field, and a .field-after (e.g. a
   "show it" box) under it; stacked on narrow screens */
@media (width >= 64rem) {
  .field-rows { display: grid; grid-template-columns: max-content minmax(0, 1fr); column-gap: 1rem; }
  .field-rows > .field { display: grid; grid-column: 1 / -1; grid-template-columns: subgrid; align-items: center; }
  .field-rows > .field > :is(label, .field-label) { grid-column: 1; grid-row: 2; margin: 0; }
  .field-rows > .field > :is(.suggest, input, textarea) { grid-column: 2; grid-row: 2; }
  .field-rows > .field > :not(label, .field-label, .suggest, input, textarea, .field-after) { grid-column: 2; grid-row: 1; }
  .field-rows > .field > .field-after { grid-column: 2; grid-row: 3; }
}
.field-after.check { margin: 0.4rem 0 0; font-size: var(--fs-s); }

/* a label with a small "i" beside it (dom.js infoTip): the "i" is a pixel
   italic, and shows its hint in the shared bubble (.choice-tip) on hover,
   keyboard focus, or a tap */
.field-label { gap: 0.4rem; }
.field-label > label { margin: 0; }
.info-tip {
  position: relative;
  isolation: isolate;
  display: inline-grid;
  place-items: center;
  width: 1rem;
  height: 1rem;
  color: var(--gray);
  font-family: var(--display);
  font-size: var(--fs-s);
  font-style: italic;
  line-height: 1;
  cursor: help;
}
/* its ring: the fields' pixel outline (the rule at the top), on a layer
   behind; quiet (gray) until hovered or opened, then orange */
.info-tip::before { content: ""; position: absolute; inset: 0; z-index: -1; --box-line: var(--tint-strong); --field-fill: var(--tint-strong); }   /* (a filled tint, no ring) */
.info-tip:is(:hover, :focus-visible, [aria-expanded="true"]) { z-index: 7; color: var(--accent); }   /* (in front, so its bubble isn't covered) */
.info-tip:is(:hover, :focus-visible, [aria-expanded="true"])::before { --box-line: var(--accent); }
.info-tip:is(:hover, :focus-visible, [aria-expanded="true"]) > .choice-tip,
.tag-add:is(:hover, :focus-visible) > .choice-tip { display: block; }
:is(.info-tip, .tag-add, .tip-host, .note-tip) > .choice-tip { font-family: var(--sans); font-style: normal; font-weight: normal; text-transform: none; letter-spacing: normal; text-align: left; white-space: normal; }   /* (not the "i"'s pixel italic, nor a tag's type) */

.summary-list .tags { margin: 0; }
/* the Rules summary: ticked rules grouped by kind, each with its qualifier
   tag and a link to change its wording */
.rule-summary-type { margin: 1.25rem 0 0.25rem; }
.rule-summary { margin: 0; padding: 0; }
.rule-summary li {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.25rem 0.75rem;
  padding: 0.5rem 0;
  border-bottom: var(--rule);
  font-size: var(--fs-s);
}
.rule-summary li > .field { flex-basis: 100%; margin-bottom: 0.5rem; }
.rule-summary .link-button { margin-left: auto; font-size: var(--fs-xs); }
.rule-original { flex-basis: 100%; order: 1; margin: 0; }
.rule-summary-own { margin-bottom: 0; }   /* (the pixel divider below spaces it from the summary) */
.next-steps { margin: 0.5rem 0 0; padding-left: 1.4em; }
.next-steps li { margin-bottom: 0.25rem; }
.next-steps li::marker { color: var(--accent); font-family: var(--mono); font-weight: 600; }
.next-steps .chip { margin-left: 0.5em; }

/* ── start: edit-an-existing-card form ───────────────────── */
.key-form label.mono-u {
  display: block;
  margin: 1.25rem 0 0.4rem;
}
.key-form .button { margin-top: 0.5rem; }

/* ── save-your-key screen ────────────────────────────────── */
.key-list { margin: 2rem 0 1rem; }
.key-list > div { margin-bottom: 1.25rem; }
.key-list dt { margin-bottom: 0.4rem; }
.key-list dd { margin: 0; }

/* the ID and secret: big enough to read, and wrapping anywhere so the
   43-character secret never pushes the page sideways */
.key-value {
  display: inline-block;
  max-width: 100%;
  margin-right: 0.75rem;
  padding: 0.35rem 0.6rem;
  background: var(--tint-strong);
  font-size: var(--fs-m);
  word-break: break-all;
  user-select: all;   /* one click selects the whole value */
}

/* ── editor sidebar (wide screens) ───────────────────────── */
/* the crow, the card's name, the buttons and Docs sit centered; the module
   list stays left-aligned */
.editor-crow {   /* the flapping header crow, perched at the top */
  --sprite: 4rem;
  margin: -0.5rem auto 1rem;
}

:is(.editor-card, .editor-actions, .editor-forget, .editor-reset, .editor-export, .editor-docs) { text-align: center; }

.editor-card { margin: 0 0 1.25rem; }
.editor-card .mono-u { display: block; }
.editor-card .editor-name { display: block; font-weight: 700; font-size: var(--fs-m); line-height: 1.3; overflow-wrap: anywhere; }
.editor-card .mono { display: block; word-break: break-all; }

/* a module with a suggestion waiting: a small neon lime pixel with stepped
   corners after its name, with a thin orange edge (following the steps) so
   it shows on beige too. The narrow-screen Modules toggle gets one when any
   module has a suggestion. */
.flag-dot {
  display: inline-block;
  width: 10px;
  height: 10px;
  margin-left: 0.45em;
  vertical-align: 0.1em;
  /* the edge: the stepped lime shape's outline, one pixel out on each side */
  filter: drop-shadow(1px 0 0 var(--accent)) drop-shadow(-1px 0 0 var(--accent)) drop-shadow(0 1px 0 var(--accent)) drop-shadow(0 -1px 0 var(--accent));
}
.flag-dot::before { content: ""; display: block; height: 100%; background: var(--lime); --px: 2px; }   /* steps: the shared clip-path (2px: big enough to show past the edge) */

/* module names are the main thing here: a step bigger than docs links */
.editor-nav .module-list a { font-size: var(--fs-xs); }

.editor-actions,
.editor-forget,
.editor-reset,
.editor-export { margin: 0 0 0.9rem; }
/* the sidebar's (and the narrow-screen bar's) Save / Forget / Reset, and a card page's Share link / Fork / downloads: smaller than other small buttons */
:is(.editor-nav-panel, .editor-bar, .card-page-actions) .button-small { --px: 2px; font-size: var(--fs-m); padding: 0.2em 0.85em 0.25em; }
.editor-docs { margin: 0; }

/* the status under Save, and "on this device" under Forget */
.save-status,
.editor-forget-note {
  min-height: 1.5em;   /* holds its space so what's below doesn't jump */
  margin: 0.5rem 0 0;
}

/* Docs: a normal link, just sized for the sidebar */
.editor-docs a { font-size: var(--fs-xs); }

/* ── editor sidebar (narrow screens): the shared slim bar (styles.css
   .sidebar-bar) ── */
@media (width < 64rem) {   /* = --narrow */
  .editor-crow { display: none; }   /* the header has the crow here */

  /* the bar: the module's name (opens the module list) and Docs on the
     left; the save status and card name, then + (Save, Forget, Reset) on
     the right, always together on one line (on very small screens that
     line moves under the first, and a long name is cut short with …) */
  .editor-bar > a { font-size: var(--fs-xs); }
  .editor-bar-end {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    min-width: 0;
    margin-left: auto;
  }
  .editor-bar-card {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    min-width: 0;
    margin: 0;
    font-size: var(--fs-xs);
  }
  /* both cut short with … if the line runs out of room: the name first */
  .editor-bar :is(.save-status, .editor-bar-name) { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .editor-bar .save-status { min-height: 0; margin: 0; }
  .editor-bar .editor-bar-name { flex-shrink: 4; min-width: 3.5em; max-width: 16rem; }   /* (always a few letters, never a sliver) */
  /* the card's ID, at the top of the + menu */
  .editor-bar-id { margin: 0 0 0.25rem; color: var(--gray); font-size: var(--fs-xs); text-align: center; white-space: nowrap; }
  .editor-bar-id .mono-u { display: block; font-size: 1em; }
  .editor-bar-more { position: relative; display: flex; }
  /* the +: bigger than the usual pixel toggle */
  #editor-bar-more { width: 2rem; height: 2rem; }
  #editor-bar-more::before { width: 15px; height: 15px; }
  #editor-bar-more:not([aria-expanded="true"], :hover, :focus-visible) { color: var(--ink); }   /* dark, so it stands out; orange when open or hovered */
  .editor-bar-menu {
    position: absolute;
    top: calc(100% + 0.5rem);
    right: 0;
    z-index: 6;
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 0.5rem;
    padding: 0.75rem;
    background: var(--bg);
    box-shadow: 0 0 0 2px var(--accent);
  }
  .editor-bar-menu[hidden] { display: none; }

  /* open, the panel is just the module list, as a wrapped row: the bar shows the rest */
  .editor-nav-panel :is(.editor-card, .editor-actions, .editor-forget, .editor-reset, .editor-export, .editor-docs) { display: none; }
  .editor-nav-panel .module-list { display: flex; flex-wrap: wrap; gap: 0 1rem; }
  .editor-nav-panel .module-list a { padding-block: 0.15rem; }
}

/* "↑ New suggestion" (js/scroll.js pointTo): a small box like the pop-ups
   (beige, orange pixel outline: the field pixel-box rule above), near the
   top of the screen, pointing up to something that appeared out of sight.
   It flashes lime twice when it appears. */
.place-pill {
  --field-fill: var(--bg);
  position: fixed;
  top: calc(var(--header-h) + 0.75rem);
  left: 50%;
  z-index: 25;
  translate: -50% 0;
  padding: 0.5em 1em;
  color: var(--ink);
  font-family: var(--mono);
  font-size: var(--fs-xs);
  cursor: pointer;
  animation: place-pill-flash 1.2s steps(1, end);
}
.place-pill:is(:hover, :focus-visible) { --field-fill: var(--lime); }
@keyframes place-pill-flash {
  0%, 50% { --field-fill: var(--lime); }
  25%, 75% { --field-fill: var(--bg); }
}
@media (prefers-reduced-motion: reduce) { .place-pill { animation: none; } }
@media (width < 64rem) { .place-pill { top: calc(var(--header-h) + 3.25rem); } }   /* below the editor's bar */

/* ── pop-up ──────────────────────────────────────────────── */
/* a box over the page for anything that needs attention: an orange pixel
   frame (the border, cut into stepped corners by the shared rule in
   styles.css) around a beige panel */
.popup {   /* outline and corners: the pixel-box rule at the top, with 4px steps */
  --box-px: 4px;
  --popup-line: var(--accent);   /* the outline: orange, or pink for an error */
  --box-line: var(--popup-line);
  --field-fill: var(--bg);
  width: min(32rem, calc(100% - var(--gutter) * 2));
  max-width: none;
  padding: 0;
  color: var(--ink);
}
.popup.is-error { --popup-line: var(--error); }
.popup.is-error .popup-title { color: var(--error); }

.popup::backdrop {
  background: var(--veil);
  backdrop-filter: blur(3px);
}

.popup-inner {
  position: relative;
  padding: 1.5rem 3.25rem 1.5rem 1.5rem;   /* room on the right for the X */
}

.popup-title {
  margin: 0 0 0.5rem;
  font-size: var(--fs-lede);
}

.popup-body > :last-child { margin-bottom: 0; }

/* a row of buttons, e.g. at the bottom of a pop-up or a suggestion */
.button-row {
  gap: 0.75rem 1.25rem;
  margin-top: 1.25rem;
}

/* close: the pixel X (its shape is the shared rule in styles.css) */
.popup-close {
  position: absolute;
  top: 0.75rem;
  right: 0.75rem;
  display: grid;
  place-items: center;
  width: 2.25rem;
  aspect-ratio: 1;
}

.popup-close span {
  --dot: 4px;
  color: var(--ink);
}

.popup-close:hover span,
.popup-close:focus-visible span { color: var(--accent); }

/* the published card's page (card-page.js): one small line above the card (version, date, view);
   under it, the versions, what it was forked from, and the actions as small text buttons */
.info-body.card-page { padding-top: 1.75rem; }   /* (the card close under the header: less room than the other pages' 4rem) */
.card-page-meta { margin: 0 0 0.75rem; font-size: var(--fs-s); }
.card-page > .card-view { margin-bottom: 1rem; }
.card-page :is(.card-versions, .card-page-note) { margin: 0.5rem 0 0; font-size: var(--fs-s); }
.card-page-actions { gap: 0.5rem; margin: 1rem 0 0; }

/* the fork pop-up (card-page.js): what's copied and what isn't, side by side, small */
.fork-lists { display: grid; grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr)); gap: 0.5rem 1.5rem; margin-bottom: 1.25rem; font-size: var(--fs-s); }
.fork-lists ul { margin: 0.25rem 0 0; }
.fork-lists li + li { margin-top: 0.1rem; }

/* ── the card (js/card-view.js): one summary box. The top (name, kinds,
   places), the description, tags and values, then each module in a light
   outline (a summary box in the line color); notes on pixel asterisk badges ── */
.card-view { container-type: inline-size; padding: 1.5rem 1.5rem 1.25rem; font-size: 0.8rem; }   /* one small size for everything but the headings: between --fs-xs (its labels) and --fs-s */
/* tags, lists and lines have no margins of their own in the card: their container
   spaces them (this rule comes before those spacings, and is no stronger, so they win) */
.card-view :where(.tags, dl, p, ul) { margin: 0; }
.card-view > * + * { margin-top: 1rem; }

/* the top: the name and TYPE • FORMAT • SIZE on the left, the places on the right */
.card-top { display: flex; flex-direction: column; gap: 0.75rem; }
.card-title a { color: inherit; font: inherit; text-transform: none; letter-spacing: normal; text-decoration: none; background: none; }
.card-title a:is(:hover, :focus-visible) { color: var(--accent); }   /* (black → orange, like the card's other hovers) */
.card-title > :is(h1, h2, h3) { margin: 0; color: var(--ink); font-style: normal; }   /* (upright and black, like the modules' headings) */
.card-kinds { margin: 0.5rem 0 0; }
/* a pixel dot between things on one line (the kinds, the platform's flags) */
.card-sep { display: inline-block; width: 6px; height: 6px; margin: 0 0.6rem; background: currentColor; vertical-align: 0.15em; }
.card-places { display: flex; gap: 0.5rem; align-items: flex-start; }
.card-places > .px-icon { flex: none; margin-top: calc(0.5lh - 8px); }   /* (under the name: the pin at 1×, centered on the line) */
.card-places li { display: inline; }   /* (under the name: one line, with commas) */
.card-places li:not(:last-child)::after { content: ", "; color: var(--ink); }
@container (width >= 36rem) {   /* (room for both: the places on the right, one under another) */
  .card-top { flex-direction: row; justify-content: space-between; align-items: flex-start; gap: 2rem; }
  .card-places > .px-icon { width: 24px; height: 24px; margin-top: calc((1lh - 1em) / 2); }   /* (the pin, 1.5×, its top level with the first place's letters) */
  .card-places li { display: block; width: fit-content; }
  .card-places li:not(:last-child)::after { content: none; }
  .card-places li + li { margin-top: 0.15rem; }
  .card-places .choice-tip { left: auto; right: 0; }   /* (at the right edge: the bubble opens leftward) */
}

/* the description: a tinted box; a long one cut to a few lines, the pixel "…" to read it whole */
.card-description { --px: 4px; position: relative; padding: 0.75rem 1rem; background: var(--tint-strong); font-size: var(--fs-s); }

/* label / answer rows: tags and values at the top; a module's facts (model, costs, other tools) */
.card-facts { display: grid; grid-template-columns: max-content minmax(0, 1fr); gap: 0.45rem 1.25rem; align-items: baseline; }
.card-facts > dd { margin: 0; }

/* modules: a light outline each (the summary box, in the line color); two side by side (Infrastructure, Membership), stacked when narrow */
.card-module { --summary-line: var(--line); container-type: inline-size; }   /* (its groups side by side or stacked by its own width) */
/* each module is its own layer (its outline isolates it; its width query contains it), so its bubbles
   can't rise above the modules after it: the one being pointed at or used comes to the front */
.card-module:is(:hover, :focus-within) { z-index: 1; }
.card-module > * + * { margin-top: 0.75rem; }
.card-module-head { display: flex; align-items: center; gap: 0.5rem; margin: 0 0 0.75rem; color: var(--ink); font-family: var(--display); font-style: normal; font-weight: 400; font-size: var(--fs-l); line-height: 1.2; }
.card-pair { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 18rem), 1fr)); gap: 1rem; align-items: stretch; }
.card-module > .card-pair { align-items: start; gap: 1.25rem 2rem; }   /* (inside a module: groups, not boxes) */
.card-stack > * + * { margin-top: 0.75rem; }   /* (a column of parts, beside a group) */
/* groups in a module, apart: a faint dotted line between them (above, when stacked; between, when side by side) */
.card-module {
  --dots-across: repeating-linear-gradient(90deg, var(--line) 0 2px, transparent 2px 6px) top / 100% 2px no-repeat;
  --dots-down: repeating-linear-gradient(180deg, var(--line) 0 2px, transparent 2px 6px) left / 2px 100% no-repeat;
}
.card-module > :is(.card-group-box, .card-pair) + :is(.card-group-box, .card-pair),
.card-module > .card-pair > * + * { padding-top: 1rem; background: var(--dots-across); }
@container (width >= 38rem) {   /* (side by side: about two 18rem columns) */
  .card-module > .card-pair > * + * { padding-top: 0; padding-left: 2rem; background: var(--dots-down); }   /* (the line in the middle of the gap) */
}
/* a group inside a module (Joining, Structure, Decision making, Conflict, Communications): a small heading, with its badge */
.card-sub { display: flex; align-items: center; gap: 0.5rem; margin: 0 0 0.5rem; font-family: var(--mono); font-size: var(--fs-xs); font-weight: 600; letter-spacing: var(--caps-spacing); }

/* a note badge (dom.js infoTip({ note })): the editor's pixel asterisk; its note in the shared bubble */
.note-tip { position: relative; display: inline-flex; }
.note-tip > .note-mark { position: relative; inset: auto; }
.card-view .tag.has-note { margin-right: 0; }   /* (on the card the badge sits inside the tag, on its text's line) */
.note-tip:has(> .note-mark:is(:hover, :focus-visible, [aria-expanded="true"])) { z-index: 7; }
.note-tip:has(> .note-mark:is(:hover, :focus-visible, [aria-expanded="true"])) > .choice-tip { display: block; }
.card-pair > :last-child .note-tip > .choice-tip { left: auto; right: 0; }   /* (on the right: the bubble opens leftward) */
.card-tip-line { display: block; }
.card-tip-line + .card-tip-line { margin-top: 0.4rem; }
.card-tip-line > b { display: block; color: var(--lime); font-size: 0.9em; }

/* pixel pills (the platform, a joining tier, the federation approach): dark, small mono capitals */
.card-pill { --px: 2px; display: inline-block; padding: 0.2em 0.6em; background: var(--ink); color: var(--bg); font-family: var(--mono); font-size: var(--fs-xs); font-weight: 600; letter-spacing: var(--caps-spacing); text-transform: uppercase; }
/* soft tags: gray (keywords, tools, lists); .tag-add (the "More like this" pills) builds on them */
.tag:is(.tag-soft, .tag-add) { background: var(--line); color: var(--ink); }
.card-group { gap: 0.4rem; }

/* yes / no on one line (protocol, open source, self-hosted; the block list, bridges): bold for yes, struck through for no */
.card-flag { font-weight: 700; white-space: nowrap; }
.card-flag:is(.is-no, .is-varies) { color: var(--gray); font-weight: 400; }
.card-flag.is-no { text-decoration: line-through; }

/* Membership: the ways of joining in two columns; the pixel icons, and the tiles they sit on (tiers, scales) */
.px-icon { width: 16px; height: 16px; fill: currentColor; shape-rendering: crispEdges; }
/* a pixel icon on a lime tile (a joining tier; a scale, bigger) */
.card-tile { display: grid; place-items: center; width: 56px; height: 56px; background: var(--lime); color: var(--ink-on-color); }   /* (the scales; the tiers, beside a heading, are smaller) */
.card-tile > .px-icon { width: 48px; height: 48px; }   /* (3× the 16-pixel grid: crisp) */
/* a module's heading with something on its right (Membership: its tiers, as tiles) */
.card-module-top { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: flex-start; gap: 0.5rem 1rem; }   /* (top-aligned: the heading sits where the other modules' do) */
.card-module-top > .card-module-head { margin: 0; }
.card-module-top .plain-list { display: flex; gap: 0.4rem; }
.card-module-top .choice-tip { left: auto; right: 0; }   /* (at the right edge: the bubble opens leftward) */
.card-module-top .card-tile { width: 40px; height: 40px; }   /* (smaller beside a heading: the tiers) */
.card-module-top .card-tile > .px-icon { width: 32px; height: 32px; }   /* (2×: crisp) */
.card-ways .tags { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 11rem), 1fr)); justify-items: start; }

/* the scales: a lime tile with its pixel icon (its name, aim and score in a bubble), and a
   column of squares filled to the score (the target, in Full, with a dotted border, its key on hover) */
.card-scales { display: flex; flex-wrap: wrap; gap: 1rem 1.25rem; }
.card-scale { display: flex; align-items: flex-end; gap: 6px; }
.card-scale-bar { display: grid; gap: 2px; }
.card-scale-bar > i { position: relative; width: 10px; height: 6px; background: var(--line); }   /* (seven, as tall as the tile) */
.card-scale-bar > i.on { background: var(--accent); }
.card-scale-bar > i.target { outline: 2px dotted var(--ink); outline-offset: -1px; }   /* (its key, "where they'd like to be", in a bubble: .tip-host) */
.card-scale-bar > i.target:is(:hover, :focus-visible) { outline-color: var(--accent); }
/* …or across (a custom module's scale answer): square cells, the ends' words either side */
.card-scale-bar.is-across { grid-auto-flow: column; }
.card-scale-bar.is-across > i { width: 10px; height: 10px; }
.card-scale-row { display: flex; flex-wrap: wrap; align-items: center; gap: 0.3rem 0.6rem; }

/* decision making: each approach, and beside it (after a short line) the areas whose notes say how it's used */
.card-decisions { display: grid; gap: 0.5rem; }
.card-decisions > li { display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem 0.6rem; }
.card-used { display: inline-flex; align-items: center; gap: 0.5rem; }
.card-used-line { width: 1rem; height: 2px; background: var(--gray); }
.card-used-areas { display: grid; color: var(--gray); font-size: 0.6rem; line-height: 1.25; }

/* steps (conflict: one under another; the response ladder: left to right), a pixel arrow between; a step's approaches side by side */
.card-steps { display: flex; flex-direction: column; align-items: flex-start; gap: 0.3rem; }
.card-steps > .flow-arrow { rotate: 90deg; margin-left: 0.4rem; }
.card-steps > .flow-arrow::after { --dot: 3px; }   /* (a bigger arrow: it stands alone between the steps) */
.card-steps-across { flex-direction: row; flex-wrap: wrap; align-items: center; }
.card-steps-across > .flow-arrow { rotate: none; }
.flow-arrow { position: relative; width: 1.75rem; height: 1rem; }
/* the pixel star (a primary step), at the text's size; and its key, on Processes' heading */
.px-star { width: 9px; height: 9px; }
.card-primary { display: inline-flex; align-items: center; gap: 0.35rem; }
.card-key { display: inline-flex; align-items: center; gap: 0.35rem; }

/* Rules and custom modules: groups in columns, each label over its list */
.card-columns-flow { columns: 2 16rem; column-gap: 2rem; }
.card-flow-group { break-inside: avoid; margin-bottom: 0.75rem; }
.card-flow-group > :is(ul, p) { margin: 0.25rem 0 0; }
.card-intro { color: var(--gray); font-size: var(--fs-s); }   /* (a custom module's description, under its heading) */
.card-flow-group > ul:not(.tags) > li + li { margin-top: 0.15rem; }   /* (a list of rules; tags keep their own row) */
/* a custom rule, under its type: a hollow bullet (an outlined pixel square), unlike the listed rules' filled ones */
.card-flow-group li.custom::before { top: calc(0.5lh - 3.5px); width: 7px; height: 7px; background: none; box-shadow: inset 0 0 0 2px var(--accent); }
.card-rules { --summary-fill: var(--tint-strong); }   /* the rules on the stronger tint, as in the sketch */
