/* items.css — Forge > Items builder + custom-items library.
   The builder reuses character.js's shell classes (char-module / char-step /
   char-nav / char-progress / field / btn) for layout + theme; this file only
   adds the Items-specific pieces: the type picker, roll blocks, choice chips,
   the library card variant, and the pre-save preview. Dark-theme tokens only. */

.item-module {
  width: 100%;
}

/* ---- Type picker --------------------------------------------------------- */

.item-type-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: var(--space-md);
  margin-top: var(--space-md);
}

.item-type-card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
  text-align: left;
  padding: var(--space-md);
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: 2px;
  color: var(--color-text);
  cursor: pointer;
  transition: border-color 0.15s ease, background-color 0.15s ease, transform 0.1s ease;
}

.item-type-card:hover,
.item-type-card:focus-visible {
  border-color: var(--color-accent);
  background-color: var(--color-surface-hover);
  outline: none;
}

.item-type-card__name {
  font-family: var(--font-heading-ui);
  font-size: var(--text-h4);
  letter-spacing: var(--ls-cinzel-caps);
  color: var(--color-heading);
}

.item-type-card__badge {
  position: absolute;
  top: var(--space-sm);
  right: var(--space-sm);
  font-family: var(--font-heading-ui);
  font-size: 0.6rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-accent);
  border: 1px solid var(--color-accent);
  padding: 0.05rem 0.35rem;
}

.item-type-card__blurb {
  font-size: 0.85rem;
  color: var(--color-text-muted);
  line-height: 1.4;
}

/* ---- Choice rows + chips (radio/checkbox groups) ------------------------- */

.item-choice-row {
  display: flex;
  gap: var(--space-md);
  align-items: center;
}

.item-choice-row--wrap {
  flex-wrap: wrap;
  gap: var(--space-sm);
}

.item-choice {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  cursor: pointer;
  color: var(--color-text);
  font-size: 0.95rem;
}

.item-choice--chip {
  padding: 0.2rem 0.55rem;
  border: 1px solid var(--color-border);
  background-color: var(--color-surface);
  border-radius: 2px;
  font-size: 0.85rem;
}

.item-choice--chip:hover {
  border-color: var(--color-accent);
}

/* ---- Inline "add a tag" control ------------------------------------------ */

.item-inline-add {
  display: flex;
  gap: var(--space-sm);
  align-items: stretch;
}

.item-inline-add .field__input {
  flex: 1 1 auto;
}

.item-textarea {
  width: 100%;
  resize: vertical;
  font-family: var(--font-body);
}

/* ---- Roll blocks (dice button + result line) ----------------------------- */

.item-roll-block {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
  align-items: flex-start;
  padding: var(--space-md);
  background-color: var(--color-oracle-bg);
  border: 1px solid var(--color-border);
  border-radius: 2px;
  margin-bottom: var(--space-md);
}

.item-roll-result {
  margin: 0;
  font-size: 0.95rem;
  color: var(--color-text);
}

.item-roll-result strong {
  color: var(--color-accent);
}

.item-roll-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
}

.item-roll-li {
  display: flex;
  align-items: flex-start;
  gap: var(--space-sm);
  padding: var(--space-sm);
  background-color: var(--color-surface);
  border-left: 2px solid var(--color-accent);
  font-size: 0.9rem;
  color: var(--color-text);
  line-height: 1.4;
}

.item-roll-li > span {
  flex: 1 1 auto;
  min-width: 0;
}

/* Reroll + remove controls grouped at the end of a rolled benefit/curse line. */
.item-roll-li__controls {
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
}

/* Remove control on a rolled benefit/curse line (spec Fix 2). */
.item-roll-remove {
  flex: none;
  appearance: none;
  border: none;
  background: none;
  cursor: pointer;
  padding: 0 var(--space-xs);
  font-size: 1.1rem;
  line-height: 1;
  color: var(--color-text-muted);
  transition: color var(--transition-ui);
}

.item-roll-remove:hover {
  color: var(--color-danger);
}

.item-roll-remove:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 1px;
}

/* ---- Inline die / random button beside a field (spec §4) ----------------- */

.item-die-row {
  display: flex;
  align-items: stretch;
  gap: var(--space-sm);
}

.item-die-row .field__input,
.item-die-row .field__select {
  flex: 1 1 auto;
  min-width: 0;
}

/* The small die button — square OSR chrome, currentColor SVG (no emoji). A
   subtle layered surface + inset top-edge highlight makes it read as a struck
   metal token rather than a flat utility button. */
.item-die-btn,
.item-reroll-btn {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.2rem;
  padding: 0;
  background-color: var(--color-surface);
  background-image: linear-gradient(180deg, rgba(255, 255, 255, 0.04), rgba(0, 0, 0, 0.18));
  border: 1px solid var(--color-border);
  border-radius: 2px;
  color: var(--color-text-muted);
  cursor: pointer;
  transition: color var(--transition-fast), border-color var(--transition-fast),
              background-color var(--transition-fast), box-shadow var(--transition-fast);
}

.item-die-btn:hover,
.item-reroll-btn:hover {
  color: var(--color-accent);
  border-color: var(--color-accent);
  background-color: var(--color-surface-hover);
  box-shadow: 0 0 0 1px var(--color-accent), 0 0 10px -2px var(--color-accent);
}

.item-die-btn:focus-visible,
.item-reroll-btn:focus-visible {
  color: var(--color-accent);
  border-color: var(--color-accent);
  background-color: var(--color-surface-hover);
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

/* Pressed: settle the token inward so a roll feels tactile. */
.item-die-btn:active,
.item-reroll-btn:active {
  transform: translateY(1px);
  box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.5);
}

.item-die-btn svg,
.item-reroll-btn svg {
  width: 1.05rem;
  height: 1.05rem;
}

/* A field label that carries an inline die button (radio-group fields). */
.item-label-row {
  display: inline-flex;
  align-items: center;
  gap: var(--space-sm);
}

.item-label-row .item-die-btn {
  width: 1.7rem;
  height: 1.7rem;
}

/* ---- Multi-part rolled name + per-part reroll (spec §5) ------------------- */

.item-name-parts {
  margin-top: var(--space-sm);
}

.item-name-parts__list {
  list-style: none;
  margin: var(--space-xs) 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-sm);
}

.item-name-part {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  padding: 0.2rem 0.2rem 0.2rem 0.55rem;
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-left: 2px solid var(--color-accent);
  border-radius: 2px;
}

.item-name-part__word {
  font-size: 0.92rem;
  color: var(--color-text);
}

.item-name-part .item-reroll-btn {
  width: 1.6rem;
  height: 1.6rem;
}

/* The noun part locked to the chosen subtype (spec Fix 1) — accent border + a
   static padlock instead of a reroll button. */
.item-name-part--locked {
  border-left-color: var(--color-accent);
}

.item-name-part__lock {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.6rem;
  height: 1.6rem;
  color: var(--color-text-muted);
}

.item-name-part__lock svg {
  width: 0.95rem;
  height: 0.95rem;
}

/* ---- Description regenerate (spec Fix 2) --------------------------------- */

.item-desc-actions {
  margin-top: var(--space-sm);
}

/* ---- Subtype material note ------------------------------------------------ */

.item-material-note {
  margin: var(--space-xs) 0 0;
  font-size: 0.85rem;
  color: var(--color-text);
}

.item-material-note strong {
  color: var(--color-accent);
}

/* ---- Image step preview (spec §3) ---------------------------------------- */

.item-image-preview {
  display: flex;
  align-items: center;
  gap: var(--space-md);
}

.item-icon-well {
  position: relative;
  flex: none;
  width: 4.5rem;
  height: 4.5rem;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: var(--color-oracle-bg, var(--color-surface));
  border: 1px solid var(--color-border);
  overflow: hidden;
}

.item-icon-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.item-icon-img--glyph {
  object-fit: contain;
  padding: 0.45rem;
}

.item-icon-glyph {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  color: var(--color-text-muted);
}

.item-icon-glyph svg {
  width: 55%;
  height: 55%;
  opacity: 0.7;
}

/* ---- Custom image upload (spec Fix 3) ------------------------------------ */

/* The native file input is visually hidden; its <label> is the styled button so
   we keep a real file-picker (accessible) without the default OS chrome. */
.item-upload {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-sm);
}

.item-upload__input {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.item-upload__btn {
  cursor: pointer;
}

/* Keyboard focus on the hidden input must show on the styled label button. */
.item-upload__input:focus-visible + .item-upload__btn {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

.item-upload__clear {
  cursor: pointer;
}

/* ---- Library cards (variant of char-card) -------------------------------- */

/* Icon + text laid out horizontally (mirrors Treasure cards, spec Fix 3). The
   base char-card__open is already display:flex; align-items:center; gap — we keep
   that, align the icon to the top, and let the body take the remaining width. */
/* The card (grid item) and its inner button (flex item) both default to
   min-width:auto, which refuses to shrink below content — that let long names
   blow the card out. Force them to shrink + clip so nothing escapes (Fix 1). */
.item-card {
  min-width: 0;
  overflow: hidden;
}

.item-card__open {
  width: 100%;
  min-width: 0;
  max-width: 100%;
  overflow: hidden;
  text-align: left;
  align-items: flex-start;
}

.item-card__body {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
  /* min-width:0 lets this flex child shrink below its content width so long
     names/meta truncate instead of pushing past the card (spec Fix 1). */
  min-width: 0;
  flex: 1 1 auto;
  overflow: hidden;
}

/* Name + meta must never overrun the card. The base char-card__name sets
   ellipsis but is an inline <span>; force block + full-width so the clamp
   actually clips (WHY: line-clamp needs a block box with a bounded width).
   The 5rem media (#2, 2026-06-27) left the single-line name a sliver, so the
   NAME is allowed to WRAP to TWO lines beside the larger icon (#5, batch-4) —
   it uses the body column's vertical room instead of clipping early. A name
   longer than two lines ellipsizes on the second line; the media is unchanged. */
.item-card .char-card__name {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  /* Allow wrapping (overrides any inherited nowrap); the clamp caps it at 2. */
  white-space: normal;
  /* Tighten leading so two lines stay compact beside the 5rem square. */
  line-height: 1.2;
}

.item-card .char-card__meta,
.item-card .char-card__updated {
  display: block;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Icon well — square OSR frame, matches the Treasure card media (spec Fix 3).
   Enlarged 3.25rem->5rem (#2, 2026-06-27) to match the larger person/building
   roster portraits so the four card types stay visually uniform. */
.item-card__media {
  position: relative;
  flex: none;
  width: 5rem;
  height: 5rem;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: var(--color-oracle-bg, var(--color-surface));
  border: 1px solid var(--color-border);
  overflow: hidden;
}

.item-card__media .item-icon-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.item-card__media .item-icon-img--glyph {
  object-fit: contain;
  padding: 0.35rem;
}

.item-card__glyph {
  width: 100%;
  height: 100%;
}

/* ----------------------------------------------------------------------------
   Item detail dashboard (item-dash) — the forged-item detail VIEW, on the shared
   char-dash --dash skin (2026-06-27, Ken; parity with bldg-dash / cmnr-dash).
   The ITEM IDIOM (KDL 2026-06-27/KDL 2026-06-27): the banner "portrait" is the SQUARE media well,
   NOT a round portrait medallion — so we override the circular base geometry the
   .char-dash__identity-portrait rule sets. Everything else inherits the --dash skin.
   ------------------------------------------------------------------------------ */
.char-dash__identity-portrait.item-dash__media {
  /* Square, not a circle — the established item media frame. */
  border-radius: 0;
  background-color: var(--color-oracle-bg, var(--color-surface));
}
.item-dash__media .item-icon-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.item-dash__media .item-icon-img--glyph {
  object-fit: contain;
  padding: 0.3rem;
}
.item-dash__media .item-icon-glyph {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
}
.item-dash__media .item-icon-glyph svg {
  /* Scaled up with the inherited 6rem hero media well (#3, 2026-06-27) so the
     item glyph fallback stays proportionate in the larger square frame. */
  width: 2.75rem;
  height: 2.75rem;
}

/* Item detail header — give the NAME room beside the 6rem hero media (#5, batch-4).
   The shared .char-dash__identity-name is white-space:nowrap + ellipsis (needed by
   the CHARACTER dashboard's measure-topbar overflow-collapse machinery). The item
   dashboard has only a tiny action row (edit + customize) and does NOT lean on that
   single-line collapse, so for ITEMS ONLY we let the name WRAP to two lines instead
   of clipping to a sliver. Scoped to .item-dash so adventurer/commoner headers and
   the shared rule are untouched, and the 6rem media is unchanged (item-dash__media
   above is not modified). */
.item-dash .char-dash__identity-namerow {
  /* The namerow is flex (name + optional chevron) — let it absorb the row width and
     wrap so a long item title fills the freed text column. */
  flex: 1 1 auto;
  min-width: 0;
}
.item-dash .char-dash__identity-name {
  white-space: normal;
  /* Cap at two lines so an extreme name still can't grow the banner unbounded;
     the second line ellipsizes. */
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-height: 1.18;
}

/* The Magic/Cursed tag row in the identity banner (reuses .item-card__tag styling). */
.item-dash__tags {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs);
}

/* The Image tab — the item's image shown LARGE, the dominant element of the tab
   body (KDL 2026-06-28: "just the image of the object that loads in the larger
   viewport"). Pattern (mirror for building/commoner/adventurer Image tabs):
     .item-dash__image-panel  = a flex column that fills the tab body
       .item-dash__image-stage  = flex:1 centered stage holding the one media frame
         .item-dash__media-large = the frame; image at object-fit:contain (whole
                                    item shows, no crop), centered
       .item-dash__image-footer = quiet provenance caption + image controls below */
.item-dash__image-panel {
  display: flex;
  flex-direction: column;
  /* The shared .char-dash__focus--notes .char-dash__panel rule caps this at 920px;
     center it in the body so the hero image sits centered, not flush-left. */
  margin-inline: auto;
}
.item-dash__image-stage {
  flex: 1 1 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  /* Make the image genuinely large in the viewport even when the surrounding body
     is short. Caps so it never grows unbounded on tall screens. */
  min-height: min(60vh, 32rem);
  padding: var(--space-md) 0;
}

/* The large image frame — the square item idiom, scaled up to fill the stage so the
   forged image dominates the view. object-fit:contain shows the WHOLE item. */
.item-dash__media-large {
  width: 100%;
  max-width: min(60vh, 32rem);
  aspect-ratio: 1 / 1;
  max-height: min(60vh, 32rem);
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--color-border);
  background-color: var(--color-oracle-bg, var(--color-surface));
  overflow: hidden;
}
.item-dash__media-large .item-icon-img {
  width: 100%;
  height: 100%;
  /* contain (not cover): the entire item is visible, centered, never cropped. */
  object-fit: contain;
  display: block;
}
.item-dash__media-large .item-icon-img--glyph {
  object-fit: contain;
  padding: 2rem;
}
/* Glyph fallback (no image) — scaled up so it reads as a deliberate placeholder at
   large size, not a broken sliver. */
.item-dash__media-large .item-icon-glyph {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 45%;
  height: 45%;
  color: var(--color-text-muted);
}
.item-dash__media-large .item-icon-glyph svg {
  width: 100%;
  height: 100%;
}

/* Quiet footer beneath the hero image — provenance caption + image controls. Kept
   secondary so the IMAGE stays dominant. */
.item-dash__image-footer {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-sm);
  text-align: center;
}
.item-dash__image-caption {
  margin: 0;
}

/* Sub-section headings inside the merged Details tab (Mechanics / Value / Lore).
   Reuses the shipped .loc-view__section-title voice; this only adds breathing room
   above every heading after the first so the three groups read as distinct
   sub-sections (KDL 2026-07-01: Value + Lore folded under Details). The first
   heading keeps its flush-top position under the panel head. */
.item-dash .char-dash__focus > .item-dash__subhead ~ .item-dash__subhead {
  margin-top: var(--space-md);
}

.item-card__tags {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs);
  margin: var(--space-xs) 0;
}

.item-card__tag {
  font-family: var(--font-heading-ui);
  font-size: 0.6rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-text-muted);
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  padding: 0.05rem 0.35rem;
  white-space: nowrap;
}

.item-card__tag--magic {
  color: var(--color-accent);
  border-color: var(--color-accent);
}

.item-card__tag--homebrew {
  color: var(--color-luck);
  border-color: var(--color-luck);
}

/* Cursed badge (spec §6) — danger-red, matches the Treasure card badge. */
.item-card__tag--cursed,
.treasure-card__tag--cursed {
  color: var(--color-danger);
  border-color: var(--color-danger);
  background-color: var(--color-danger-bg);
}

/* Mithral material note badge on the preview card. */
.treasure-card__tag--mithral {
  color: var(--color-accent);
  border-color: var(--color-accent);
}

/* ---- Pre-save preview ---------------------------------------------------- */

.item-preview {
  margin: var(--space-md) 0;
  max-width: 420px;
}

.item-preview-card {
  /* The preview card is a static (non-clickable) variant of treasure-card. */
  cursor: default;
}

.item-detail__desc {
  margin-top: var(--space-md);
  max-width: 640px;
}

.item-detail__desc p {
  margin: 0;
  line-height: var(--lh-body);
}

/* ---- Single editable card (UI experiment) --------------------------------- */

/* The editor IS the item/treasure card: one large centered card whose every
   attribute is an inline-editable control. Replaces the old form+preview-aside
   split. min-width:0 throughout keeps it from overflowing horizontally; it is
   intentionally tall and scrolls the page vertically.

   Padding rhythm (Ken's ask): the card is generously padded with MORE on the
   left, where the eye starts each row. These three custom props drive every
   section/header/footer so the gutters stay consistent, and they relax at small
   widths (see the media query) so the extra left padding never causes overflow. */
.item-form {
  min-width: 0;
  --item-pad-y: var(--space-lg);     /* 24px — comfortable vertical breathing room */
  --item-pad-right: var(--space-lg); /* 24px */
  --item-pad-left: var(--space-2xl); /* 48px — Ken: more padding on the LEFT */
}

.item-form__topbar {
  display: flex;
  align-items: center;
  gap: var(--space-md);
  flex-wrap: wrap;
  margin-bottom: var(--space-md);
  max-width: 760px;
  margin-left: auto;
  margin-right: auto;
  padding-left: var(--space-sm);
}

.item-form__title {
  margin: 0;
}

/* Section heading inside the card (Subtype / Damage / Description / ...). A
   small-caps Cinzel label with a short torchlight tick to its left so each
   group reads as an engraved divider, on-brand with the OSR aesthetic.

   ALIGNMENT (padding fix #0): the heading TEXT must share the exact left edge of
   the field labels/inputs beneath it. The torchlight tick is therefore pulled
   into the gutter (negative left margin = tick width + gap) so it sits LEFT of
   that shared edge instead of pushing the heading text rightward. Every
   section's heading and field rows now align to one uniform left gutter. */
.item-form__heading {
  --item-heading-tick: 0.85rem;
  margin: 0;
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  /* Pull the heading box left by the tick + gap so its TEXT lands on the same
     left edge as the .field labels (which have no leading tick). */
  margin-left: calc(-1 * (var(--item-heading-tick) + var(--space-sm)));
  font-family: var(--font-heading-ui);
  font-size: var(--text-sm);
  text-transform: uppercase;
  letter-spacing: var(--ls-cinzel-caps);
  color: var(--color-heading);
}

.item-form__heading::before {
  content: "";
  flex: none;
  width: var(--item-heading-tick);
  height: 2px;
  background-color: var(--color-accent);
  box-shadow: 0 0 6px -1px var(--color-accent);
}

/* The big card — styled on the treasure-card look (surface, sharp OSR corners,
   left accent rule), centered, capped so it reads as a single object. A faint
   grain + raised shadow lift it off the page; a torch-glow inset on the accent
   edge ties the left rule into the heading ticks. */
.item-edit-card {
  min-width: 0;
  max-width: 760px;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  background-color: var(--color-surface);
  background-image: var(--grain);
  border: 1px solid var(--color-border);
  border-left: 3px solid var(--color-accent);
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.03) inset,
              0 8px 28px -12px rgba(0, 0, 0, 0.7),
              -8px 0 22px -18px var(--color-accent);
}

/* Header: media well (with upload/remove) + name/type/badges, like the treasure
   card header but editable. Slightly deeper surface + heavier divider mark it as
   the card's masthead. */
.item-edit-card__header {
  display: flex;
  /* Top-align the media well with the heading column so the icon sits level
     with the NAME label/input row rather than floating against the title
     baseline (icon/name alignment, label-polish). A small top nudge on the
     well (below) lines its top edge up with the cap-height of the label. */
  align-items: flex-start;
  gap: var(--space-lg);
  flex-wrap: wrap;
  padding: var(--item-pad-y) var(--item-pad-right) var(--item-pad-y) var(--item-pad-left);
  background-color: var(--color-oracle-bg);
  border-bottom: 1px solid var(--color-border);
}

.item-edit-card__media {
  flex: none;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-sm);
  /* Drop the well + its actions to line the well's vertical centre up with the
     name input (the label sits above). The label height + its margin is roughly
     one small-caps line, so nudging the media down by that much aligns the icon
     to the title input, not the label. */
  margin-top: calc(var(--text-sm) + var(--space-xs));
}

/* A larger square frame than the library card — the card's hero icon, framed
   with a subtle inner shadow so the art sits in the well. */
.item-edit-card__well {
  width: 5.5rem;
  height: 5.5rem;
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.4), inset 0 2px 8px rgba(0, 0, 0, 0.45);
}

.item-edit-card__media-actions {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
  width: 5.5rem;
}

/* Compact text buttons under the media well; the file input is visually hidden
   (.item-upload__input) and its label is the styled Upload/Replace button. */
.item-edit-card__media-btn {
  appearance: none;
  display: block;
  width: 100%;
  text-align: center;
  padding: 0.25rem 0.4rem;
  font-family: var(--font-heading-ui);
  font-size: 0.62rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-text-muted);
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: 2px;
  cursor: pointer;
  transition: color var(--transition-fast), border-color var(--transition-fast),
              background-color var(--transition-fast);
}

.item-edit-card__media-btn:hover,
.item-edit-card__media-btn:focus-visible {
  color: var(--color-accent);
  border-color: var(--color-accent);
  background-color: var(--color-surface-hover);
  outline: none;
}

.item-upload__input:focus-visible + .item-edit-card__media-btn {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

.item-edit-card__heading {
  flex: 1 1 16rem;
  min-width: 0;
  display: flex;
  flex-direction: column;
  /* Even vertical rhythm between the three header blocks (Name / Type / badges)
     so the masthead reads as a tidy stack rather than crowded rows. */
  gap: var(--space-lg);
}

/* Header section labels (NAME / TYPE) share ONE treatment — the same engraved
   small-caps heading the body sections (Subtype / Damage / ...) use — so every
   label in the card reads in one consistent language (label-polish #1). The
   Name label is therefore styled as an .item-form__heading-equivalent: small,
   uppercase, accent-ticked. (TYPE already uses .item-form__heading.) */
.item-edit-card__heading .field__label {
  font-family: var(--font-heading-ui);
  font-size: var(--text-sm);
  text-transform: uppercase;
  letter-spacing: var(--ls-cinzel-caps);
  color: var(--color-heading);
  margin-bottom: var(--space-xs);
}

/* The name input stays the card's prominent title — heading-scale type — but
   now sits under a consistent small label, so the hierarchy is
   label > large name input > type chips > badges. */
.item-edit-card__heading #item-name {
  font-family: var(--font-heading-ui);
  font-size: var(--text-h3);
  line-height: var(--lh-heading);
  color: var(--color-heading);
  padding: 0.3rem 0.6rem;
}

.item-edit-card__heading #item-name::placeholder {
  font-size: var(--text-h4);
}

/* "Magical?" checkbox (spec #1) — sits in the card header under the type meta,
   for the flaggable base types (weapon/armor/gear). Checking it reveals the
   gated magic field sections + flips the Magic badge. A bordered, accent-tinted
   row so it reads as a meaningful mode switch, not just another tag. */
.item-magical-toggle {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
  padding: var(--space-sm) var(--space-md);
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-left: 2px solid var(--color-accent);
  border-radius: 2px;
}

.item-magical-toggle__label {
  font-family: var(--font-heading-ui);
  letter-spacing: var(--ls-cinzel-caps);
  text-transform: uppercase;
  font-size: var(--text-sm);
  color: var(--color-heading);
}

.item-magical-toggle .field__hint {
  margin: 0;
}

/* Live badges (Magic / Cursed / Homebrew / Mithral) under the name. */
.item-edit-card__badges {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs);
}

.item-edit-card__badge {
  font-family: var(--font-heading-ui);
  font-size: 0.6rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-text-muted);
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  padding: 0.1rem 0.4rem;
  white-space: nowrap;
}

.item-edit-card__badge--magic {
  color: var(--color-accent);
  border-color: var(--color-accent);
}

.item-edit-card__badge--homebrew {
  color: var(--color-luck);
  border-color: var(--color-luck);
}

.item-edit-card__badge--cursed {
  color: var(--color-danger);
  border-color: var(--color-danger);
  background-color: var(--color-danger-bg);
}

.item-edit-card__badge--mithral {
  color: var(--color-accent);
  border-color: var(--color-accent);
}

/* Body: the chosen type's field sections, stacked. Each section is a divided
   stat-row block (reuses .field / die-row / roll-block pieces unchanged). */
.item-edit-card__body {
  display: flex;
  flex-direction: column;
}

/* Both section variants share ONE gutter so headings + fields align uniformly
   (padding fix #0). .item-edit-card__section wraps Subtype/Description (rendered
   in renderForm); .item-form__section wraps the chosen type's field groups
   (rendered by formSectionHTML). Previously only the former carried the gutter,
   so the type-field sections sat at zero left padding while Subtype/Description
   sat at the deep gutter — a non-uniform left edge. Giving both the same padding
   + dividers makes the entire card share one left gutter. */
.item-edit-card__body > .item-edit-card__section,
.item-edit-card__body > .item-form__section {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
  padding: var(--item-pad-y) var(--item-pad-right) var(--item-pad-y) var(--item-pad-left);
  border-bottom: 1px solid var(--color-border);
}

/* Hairline divider between sections, hue-shifted toward the accent so the rule
   reads as torchlit rather than a flat box border. */
.item-edit-card__body > .item-edit-card__section + .item-edit-card__section,
.item-edit-card__body > .item-form__section + .item-form__section,
.item-edit-card__body > .item-edit-card__section + .item-form__section,
.item-edit-card__body > .item-form__section + .item-edit-card__section {
  border-top: 1px solid rgba(100, 149, 237, 0.08);
}

.item-edit-card__body > .item-edit-card__section:last-child,
.item-edit-card__body > .item-form__section:last-child {
  border-bottom: none;
}

/* Within a section: align every field's label above its control, and pull the
   group note tight under the heading. The .field grid + die-row keep the input
   and its die button aligned on one row (see .item-die-row). */
.item-edit-card__body .field + .field {
  margin-top: var(--space-xs);
}

.item-edit-card__body .item-edit-card__section .char-step__note,
.item-edit-card__body .item-form__section .char-step__note {
  margin-top: calc(-1 * var(--space-xs));
}

.item-edit-card__hint {
  padding: var(--item-pad-y) var(--item-pad-right) var(--item-pad-y) var(--item-pad-left);
}

/* Footer: Cancel + Save row at the bottom of the card. Sticks to the viewport
   bottom so the primary action is always reachable on the tall card, with a
   slim torch rule and a backdrop so content scrolls cleanly beneath it. */
.item-edit-card__footer {
  position: sticky;
  bottom: 0;
  z-index: 2;
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: var(--space-sm);
  padding: var(--space-md) var(--item-pad-right) var(--space-md) var(--item-pad-left);
  background-color: var(--color-oracle-bg);
  border-top: 1px solid var(--color-accent);
  box-shadow: 0 -6px 16px -10px rgba(0, 0, 0, 0.8);
}

/* Save is the clear primary; let it carry a touch more weight than Cancel. */
.item-edit-card__footer .btn--primary {
  font-weight: 600;
}

/* The type-chip row (compact radio chips). */
.item-type-chip {
  position: relative;
}

.item-type-chip {
  transition: border-color var(--transition-fast), background-color var(--transition-fast),
              box-shadow var(--transition-fast);
}

.item-type-chip:hover {
  border-color: var(--color-accent);
}

.item-type-chip:focus-within {
  border-color: var(--color-accent);
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

.item-type-chip--active {
  border-color: var(--color-accent);
  color: var(--color-heading);
  background-color: var(--color-surface-hover);
  box-shadow: inset 0 0 0 1px var(--color-accent);
}

/* Inline "Magic" badge inside a type chip / fixed-type label (static, not the
   absolutely-positioned card badge). */
.item-type-card__badge--inline {
  position: static;
  display: inline-block;
  margin-left: var(--space-xs);
  vertical-align: middle;
}

.item-form__type-fixed {
  margin: 0;
  font-size: 1rem;
  color: var(--color-text);
}

/* The Type selector renders inside the card header rather than as a full-width
   stacked section. Keep it tight — it's the type/subtype meta line directly
   under the title. The heading + chips get even spacing so the chips never
   crowd the name input above them (label-polish). */
.item-edit-card__heading .item-form__section--type {
  gap: var(--space-sm);
  padding: 0;
  border: none;
}

/* Chips sit in their own tidy row with a touch more breathing room than the
   default wrap gap, so the MAGIC/type chips read as an aligned set rather than a
   crowded block butting against the field above. */
.item-edit-card__heading .item-form__section--type .item-choice-row--wrap {
  gap: var(--space-sm);
  row-gap: var(--space-sm);
  align-items: stretch;
}

/* Uniform chip sizing so the row reads as an aligned set — every chip the same
   height with its label (and any inline Magic badge) vertically centred, so a
   chip carrying a badge doesn't sit taller than its neighbours. */
.item-edit-card__heading .item-type-chip {
  display: inline-flex;
  align-items: center;
}

.item-edit-card__heading .item-type-chip > span {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
}

/* The inline Magic badge inside a chip is meta — keep it from adding chip
   height or crowding the type label. */
.item-edit-card__heading .item-type-chip .item-type-card__badge--inline {
  margin-left: 0;
}

/* The type-picker note under the chips is meta chrome — keep it tight + small so
   the header hierarchy (title > type meta > badges) stays clean. */
.item-edit-card__heading .item-form__section--type .char-step__note {
  margin-top: 0;
}

/* Tablet/narrow: relax the extra left padding progressively so the generous
   gutter never forces horizontal overflow on smaller screens (Ken's constraint:
   the left-padding increase must reduce gracefully at narrow widths). */
@media (max-width: 820px) {
  .item-form {
    --item-pad-left: var(--space-xl);   /* 32px */
    --item-pad-right: var(--space-md);  /* 16px */
    --item-pad-y: var(--space-md);
  }
}

@media (max-width: 700px) {
  .item-form {
    --item-pad-left: var(--space-lg);   /* 24px — still a touch more than right */
    --item-pad-right: var(--space-md);
  }
}

/* Narrow: let the media well + heading stack so nothing overflows, and drop the
   gutters to a tight uniform pad. */
@media (max-width: 560px) {
  .item-form {
    --item-pad-left: var(--space-md);
    --item-pad-right: var(--space-md);
  }

  .item-edit-card__media,
  .item-edit-card__media-actions,
  .item-edit-card__well {
    width: auto;
  }
}
