/* ==========================================================================
   mu-online-attributes.css (realm edition: dark lava + gold, tokens from css/realm/ui.css)
   Game database pages: /items (list, /items/jewels, /items/{slug}),
   /skills (list, /skills/{slug}) and /maps. Loaded only by items.php,
   skills.php and maps.php, after style.css and ui.css.

   The shell, page header, cards, tables (.table-wrap + .data-table), forms
   (.filter-bar + .field), buttons, pills, stat tiles, alerts, pagination and
   the CTA band all come from ui.css. This file only holds what is specific
   to these pages. Design tokens only; no :root overrides, no !important.
   ========================================================================== */

/* --- Page header: fallback intro (shown only when no page copy exists) --- */
.page-header .db-intro { font-size: var(--fs-base); }
.db-intro ul { margin: 0 0 var(--sp-4); padding-left: 1.25em; }
.db-intro li { margin: .3em 0; }
.db-intro > :last-child { margin-bottom: 0; }

/* --- List pages: compact page header (ux#3). Kicker off, smaller title, one tighter lead, so the search box
       sits on the first screen of a 1366x657 laptop. The "Updated" source line now closes the list card. --- */
.page-header.page-header--compact { gap: var(--sp-3); padding: clamp(12px, 1.6vw, 22px) 0 clamp(14px, 1.4vw, 18px); }
.page-header--compact .page-header__body { gap: var(--sp-2); }
.page-header--compact .page-kicker { display: none; }
.page-header--compact .page-title { font-size: clamp(1.375rem, 1rem + 1.1vw, 1.875rem); }
.page-header--compact :is(.page-lead, .page-subtitle) { max-width: 132ch; font-size: var(--fs-base); line-height: 1.55; }
.page-header--compact .page-lead__more { margin-top: 0; }
.page-header--compact .page-lead__more > summary { min-height: 28px; }
@media (min-width: 900px) {
  .page-header--compact:not(.page-header--banner) .page-title { max-width: none; }
}
.page-container > .page-header--compact + .db-tool { margin-top: var(--sp-3); }

/* --- The tool: shortcut bar + filters + list (ux#2). The bar is the shared sticky .page-jump (ux#5, tech#7:
       includes/page_jump.php + css/realm/page-jump.css, as on /events and the realm hub); .db-tool is its
       .page-jump-scope, so it sticks only while filters and list are on screen and never sits next to the codex
       rail further down. page-jump.css also gives every [id] in the tool (sections, map rows) the anchor clearance. --- */
.db-tool > * + * { margin-top: var(--sp-5); }   /* filters and list read as one tool */
.db-tool > .page-jump + * { margin-top: var(--sp-3); }
/* A deep-linked row (/maps#map-devias, the 301 of /maps/<slug>, the "Where to level" links) shows which row was
   meant (ux#0, tech#2). 0,3,3 beats the ui.css zebra and hover rules (0,2,3). */
.db-table tbody tr[id]:target > td { background: rgba(245,201,80,.12); }
.db-table tbody tr[id]:target > td:first-child { box-shadow: inset 3px 0 0 var(--gold); }
@media (forced-colors: active) {
  .db-table tbody tr[id]:target > td:first-child { outline: 2px solid Highlight; outline-offset: -2px; }
}

/* --- Filters card --- */
.db-help { margin: 0 0 var(--sp-4); max-width: var(--measure); color: var(--text-muted); }
.db-tool .card__title { margin-bottom: var(--sp-3); font-size: var(--fs-h3); }
.filter-bar > .field.db-field--wide { flex: 2 1 280px; }
.filter-bar > .field.db-field--narrow { flex: 1 1 130px; }
.filter-bar > .cluster.db-filter-actions { flex: 0 0 auto; }
.filter-bar.db-filter-bar > .field { flex: 1 1 160px; }
.filter-bar.db-filter-bar > .field.db-field--wide { flex: 2 1 260px; }
.filter-bar.db-filter-bar > .field.db-field--level { flex: 1 1 180px; }
/* min and max level share one field: two inputs and a dash in one cell */
.db-level-pair { display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); align-items: center; gap: 6px; }
.db-level-sep { color: var(--text-muted); }
/* /items: search and buttons on the first row, the four filters on the second, at every desktop width */
@media (min-width: 900px) {
  .filter-bar.db-filter-bar--items { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)) auto; }
  .filter-bar.db-filter-bar--items > .field.db-field--wide { grid-column: 1 / 5; }
  .filter-bar.db-filter-bar--items > .db-filter-actions { grid-column: 5; grid-row: 1; }
}
/* Phones (ux#4): the first results sit on the first screen. The card title and field labels stay for screen
   readers only (the selects name themselves: "All classes", "All categories"; the level inputs say Min / Max),
   the search box spans the card, the other fields pair up, and Search / Reset hide: filtering is live, so they
   return (Reset is useful then) only once a filter is set (the page script toggles .has-filters). */
@media (max-width: 639.98px) {
  .db-filters > .card__title,
  .filter-bar.db-filter-bar > .field > label { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }
  .db-tool .db-filters { padding-block: 14px; }
  .filter-bar.db-filter-bar { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
  .filter-bar.db-filter-bar > .field { min-width: 0; }
  .filter-bar.db-filter-bar > .field.db-field--wide,
  .filter-bar.db-filter-bar--maps > .field { grid-column: 1 / -1; }
  .filter-bar.db-filter-bar > .db-filter-actions { display: none; }
  .db-filters.has-filters .filter-bar.db-filter-bar > .db-filter-actions { display: flex; grid-column: 1 / -1; }
}
.db-results-meta { margin: var(--sp-4) 0 0; font-size: var(--fs-sm); color: var(--text-muted); }
.db-results-meta strong { color: var(--text-strong); }
/* the list card opens with its title and the live result line on one row; the data source line closes it */
.db-list-head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: var(--sp-2) var(--sp-5); margin-bottom: var(--sp-4); }
.db-list-head .card__title { margin: 0; }
.db-list-head .db-results-meta { margin: 0; }
.db-source { margin-top: var(--sp-4); }
.db-source .copy-updated { font-size: var(--fs-xs); color: var(--text-muted); }
:is(.db-count, #item-results-count, #skill-results-count) {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 2.2em;
  padding: 1px 8px;
  border-radius: var(--r-pill);
  background: rgba(245,201,80,.12);
  border: 1px solid var(--gold-line);
  color: var(--gold);
  font-weight: 700;
  box-shadow: 0 0 12px rgba(245,201,80,.12);
  font-variant-numeric: tabular-nums;
}

/* --- List tables (items, jewels, skills, maps) --- */
.db-table td { vertical-align: top; }
.db-table :is(.item-id-cell, .skill-col-index, .map-id-cell, .db-id-cell) { width: 1%; white-space: nowrap; font-weight: 700; color: var(--text-strong); }
.db-table :is(.item-cell, .map-name-cell) { min-width: 260px; }
.db-table .skill-col-name { min-width: 200px; }
.db-table .skill-col-role { white-space: nowrap; }
.db-table :is(.item-class-cell, .skill-col-classes) { min-width: 160px; color: var(--text-muted); }
.db-table .skill-col-classes { min-width: 220px; }
/* ux#3: in the site languages whose column headings run long (de, fr, nl, pl, ro, tr) the role may wrap and the
   class line starts at 170px below 1440px (ro, tr: below 1680px, where the page widens), so the 12-column /skills table fits its frame
   from 1280px in every language and its headings can stay pinned (en, es, pt and vi fit as they are and keep
   one-line roles) */
@media (min-width: 640px) and (max-width: 1439.98px) {
  :is(:lang(de), :lang(fr), :lang(nl), :lang(pl)) .db-table .skill-col-role { white-space: normal; }
  :is(:lang(de), :lang(fr), :lang(nl), :lang(pl)) .db-table .skill-col-classes { min-width: 170px; }
}
@media (min-width: 640px) and (max-width: 1679.98px) {
  :is(:lang(ro), :lang(tr)) .db-table .skill-col-role { white-space: normal; }
  :is(:lang(ro), :lang(tr)) .db-table .skill-col-classes { min-width: 170px; }
}
.db-table .item-stat-cell { white-space: nowrap; }
.db-table code,
.faq-list code {
  padding: .1em .35em;
  border-radius: 4px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  color: var(--gold-ink);
  font-family: var(--font-mono);
  font-size: .8125rem;
}
.db-table td > code { white-space: nowrap; }
#skill-table thead th { white-space: normal; vertical-align: bottom; }

/* Column headings stay on screen in the long lists (ux#3): they pin just under the sticky jump bar, so the eight
   numeric /skills columns never scroll by unlabelled. Sticky needs a frame that does not scroll sideways, so
   mu_page_jumpbar_script() marks a table that fits its frame .table-wrap--fits, and that frame clips (keeping its
   round corners) instead of scrolling; a wider table (tablets on /skills) keeps its side-scroller and its
   headings scroll with it. Phones (card rows, one visible heading) keep the plain list. The opaque base colour
   under the heading gradient hides the rows passing beneath; row anchors (/maps#map-…) and focused row links
   clear the pinned row by its measured height (--db-thead-h). */
@media (min-width: 640px) {
  .db-tool .table-wrap.table-wrap--fits { overflow: visible; overflow: clip; }
  .db-tool .table-wrap--fits > .db-table > thead th { position: sticky; top: calc(var(--header-h) + var(--page-jump-top, 8px) + var(--page-jump-h, 46px) + 6px); z-index: 3; background-color: var(--surface-0); }
  /* the strip between the site header and the pinned headings (where the jump bar floats) is filled too, so rows do
     not peek out above the heading row; the frame's clip trims it to the table while the headings are unpinned
     (only where overflow: clip exists, so it can never cover the list title above an unpinned table) */
  @supports (overflow: clip) {
    .db-tool .table-wrap--fits > .db-table > thead th::before { content: ""; position: absolute; left: 0; right: 0; bottom: 100%; height: calc(var(--page-jump-top, 8px) + var(--page-jump-h, 46px) + 6px); background: var(--surface-0); pointer-events: none; }
  }
  .db-tool .table-wrap--fits > .db-table > tbody :is(tr[id], a, button) { scroll-margin-top: calc(var(--db-thead-h, 52px) + 6px); }
}

.item-row-meta {
  margin-top: 4px;
  font-size: var(--fs-xs);
  font-weight: 600;
  color: var(--text-muted);
}
/* (the generated row sentences .item-row-desc / .skill-row-desc are gone from the lists: ux#3) */
.item-role-pill {
  display: inline-flex;
  align-items: center;
  margin-left: 6px;
  padding: 1px 8px;
  border-radius: var(--r-pill);
  background: var(--brand-soft);
  border: 1px solid var(--brand-line);
  color: var(--accent-text);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  white-space: nowrap;
}

/* "Show more results" (filtered mode, toggled by the inline script) */
.db-show-more { display: flex; justify-content: center; margin-top: var(--sp-5); }
.db-show-more[hidden] { display: none; }

/* Empty state inside the list (ux#7): built by the filter script when nothing matches */
.db-table tr.db-empty-row > td { padding: var(--sp-6) var(--sp-4); text-align: center; vertical-align: middle; }
.db-table tr.db-empty-row[hidden] { display: none; }
.db-empty { display: grid; justify-items: center; gap: var(--sp-3); }
.db-empty__text { margin: 0; max-width: var(--measure); color: var(--text-strong); font-weight: 600; overflow-wrap: anywhere; }
.db-empty__actions { justify-content: center; }

/* --- Item detail: the two key values in one half-width row (art#4), then the requirement tiles --- */
.stat-grid.item-key-stats { grid-template-columns: repeat(auto-fit, minmax(min(100%, 240px), 1fr)); }
.item-key-stats + .item-mini-stats { margin-top: var(--sp-3); }
.item-mini-stats .stat.is-wide { grid-column: 1 / -1; }
:is(.item-mini-stats, .item-key-stats) .stat.is-zero { background: var(--surface-0); box-shadow: none; }
:is(.item-mini-stats, .item-key-stats) .stat.is-zero .stat__value { color: var(--text-muted); font-weight: 600; }
:is(.item-mini-stats, .item-key-stats) .stat__value { overflow-wrap: anywhere; }
@media (max-width: 639.98px) {
  .stat-grid.item-mini-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }   /* six small requirement tiles in pairs, not one per row */
}

.class-pill-list { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin: 0; padding: 0; list-style: none; }
.class-pill {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  max-width: 100%;
  padding: 6px 12px 6px 8px;
  border-radius: var(--r-pill);
  border: 1px solid var(--border-strong);
  background: linear-gradient(180deg, rgba(255,196,140,.05), rgba(255,196,140,.015)), var(--surface-1);
  box-shadow: var(--bevel);
  transition: border-color var(--dur-fast), box-shadow var(--dur-fast);
}
.class-pill:hover { border-color: var(--gold-line); box-shadow: var(--bevel), var(--glow-gold); }
a.class-pill { color: inherit; text-decoration: none; }   /* item pages: each pill opens its class page (ux#2) */
a.class-pill:hover .class-pill-sub { color: var(--gold); }
.class-pill-icon { flex: 0 0 auto; width: 18px; height: 18px; border-radius: 50%; background: radial-gradient(circle at 50% 42%, rgba(245,201,80,.32), rgba(245,201,80,0) 72%); filter: drop-shadow(0 0 2px rgba(245,201,80,.45)); }   /* dark class figures keep a silhouette on obsidian */
.class-pill-text { display: flex; flex-direction: column; min-width: 0; line-height: 1.2; }
.class-pill-short { font-size: var(--fs-xs); font-weight: 700; letter-spacing: var(--ls-caps); text-transform: uppercase; color: var(--gold); }
.class-pill-sub { font-size: var(--fs-sm); font-weight: 600; color: var(--text-strong); }

/* --- Skill detail: the stats are the item page's tiles (.item-key-stats / .item-mini-stats, ux#2 + art#8) --- */
/* the generated explanation (en/ph, below the numbers) fills its card in two columns from 900px instead of one
   measure-wide column next to an empty right half (art#8) */
@media (min-width: 900px) {
  .skill-details .skill-detail-body { columns: 2; column-gap: var(--sp-6); }
  .skill-details .skill-detail-body p { max-width: none; }
}
.skill-class-list { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin: 0 0 var(--sp-4); padding: 0; list-style: none; }
.skill-class-list > li { display: flex; }
.skill-class-chip {
  display: inline-flex;
  flex-direction: column;
  gap: 2px;
  padding: 6px 12px;
  border-radius: var(--r-md);
  border: 1px solid var(--border-strong);
  background: linear-gradient(180deg, rgba(255,196,140,.05), rgba(255,196,140,.015)), var(--surface-1);
  box-shadow: var(--bevel);
  line-height: 1.25;
  color: inherit;
  text-decoration: none;
  transition: border-color var(--dur-fast), box-shadow var(--dur-fast);
}
a.skill-class-chip:hover { border-color: var(--gold-line); box-shadow: var(--bevel), var(--glow-gold); }
a.skill-class-chip:hover .skill-class-name { color: var(--gold); }
.skill-class-name { font-size: var(--fs-sm); font-weight: 700; color: var(--text-strong); }
.skill-class-stage { font-size: var(--fs-xs); color: var(--text-muted); }
.skill-detail-note { margin: 0; font-size: var(--fs-sm); color: var(--text-muted); }

/* /maps (ux#6): a player codex, not a server-file listing. The name is plain text (the row id stays the anchor);
   repeated instances are numbered ("Kalima 3"); the ATT file and its share count are a quiet note after the name
   on desktop; the freed column says when to go there (from the "Where to level" guide), linked to that guide. */
.db-table .map-name-cell { min-width:0; }
.db-table .map-name { color: var(--text-strong); white-space: nowrap; }
.map-row-file { display: inline-block; margin-left: 10px; font-size: var(--fs-xs); line-height: 1.4; color: var(--text-muted); white-space: nowrap; }
.db-table .map-row-file code { padding: 0; border: 0; background: none; color: inherit; font-size: .75rem; }
.db-table .map-role-cell { min-width:11rem; }
.db-table .map-stage-cell { white-space: nowrap; color: var(--text-muted); }
.map-stage-cell a { color: var(--accent-text); font-weight: 600; text-decoration: none; }
.map-stage-cell a:hover { color: var(--accent-text-hover); text-decoration: underline; }

/* /maps: Null.att / Reserved placeholder IDs read as muted data, not as map links (art#4); hidden until the
   "Show unused map IDs" switch under the table is on (ux#6) */
.db-table .map-row--unused td { color: var(--text-subtle); font-weight: 400; }
.map-unused { font-style: italic; color: var(--text-subtle); }
.map-unused-toggle { display: flex; align-items: center; gap: 10px; width: max-content; max-width: 100%; min-height: 44px; margin: var(--sp-3) 0 0; font-size: var(--fs-sm); color: var(--text-muted); cursor: pointer; }
.map-unused-toggle input { flex: none; width: 18px; height: 18px; margin: 0; accent-color: var(--gold); cursor: pointer; }

/* /maps on phones (art#3): ID and name only, role and leveling stage under the name; no side-scroller. The .att
   note stays on desktop (it would push the row past the frame). */
.map-row-sub { display: none; }
@media (max-width: 639.98px) {
  #map-table { min-width: 0; }
  #map-table :is(th, td):nth-child(n + 3) { display: none; }
  #map-table .map-name-cell { padding-top: 10px; padding-bottom: 10px; }
  #map-table .map-name { white-space: normal; }
  #map-table .map-row-file { display: none; }
  #map-table .map-row-sub { display: block; margin-top: 2px; font-size: var(--fs-xs); line-height: 1.4; color: var(--text-muted); }
}

/* /skills rows (art#2, ux#0): short class line; on phones one card per row like /items: name, then
   role · level · damage and the classes, clamped to two lines. Only cells are hidden; the table stays a table. */
.skill-row-sub { display: none; }
@media (max-width: 639.98px) {
  #skill-table { min-width: 0; }
  #skill-table :is(th, td):not(:nth-child(2)) { display: none; }
  #skill-table .skill-col-name { min-width: 0; padding: 12px; }
  #skill-table .skill-row-sub { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; margin-top: 4px; font-size: var(--fs-xs); line-height: 1.4; color: var(--text-muted); }
  #skill-table .skill-row-stat { color: var(--text-strong); font-weight: 600; }
  #skill-table .skill-row-stat::after { content: " · "; content: " · " / ""; color: var(--text-muted); font-weight: 400; }
  /* the empty-state row spans the table (it is the first cell, which the card rule would hide) */
  :is(#item-table, #skill-table) tr.db-empty-row > td { display: table-cell; }
}

/* --- Item rows (art#5): fixed sprite frame + name + meta line; the frame never resizes, so lazy images do not shift --- */
.item-card { display: flex; align-items: center; gap: 12px; min-width: 0; }
.item-card__text { min-width: 0; }
.item-icon {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 44px;
  height: 52px;
  border: 1px solid rgba(245,201,80,.22);
  border-radius: 8px;
  background: radial-gradient(circle at 50% 42%, rgba(245,201,80,.14), rgba(0,0,0,0) 70%), #0d0907;
  box-shadow: inset 0 0 0 1px rgba(0,0,0,.6);
}
.item-icon img { display: block; width: auto; height: auto; max-width: 36px; max-height: 44px; }
.item-icon--none::before { content: ""; width: 9px; height: 9px; border: 1px solid rgba(245,201,80,.3); transform: rotate(45deg); }   /* no sprite: a quiet gem mark keeps the column even */
.item-row-sub { display: none; }   /* phone card line, see below */

/* Phones (art#5, ux#3): one card per row instead of a 640px side-scroller. ID, stat and class columns hide;
   the card repeats stat + classes (clamped to two lines). Native table semantics stay: only cells are hidden. */
@media (max-width: 639.98px) {
  #item-table { min-width: 0; }
  #item-table :is(th, td):not(:nth-child(2)) { display: none; }
  :is(#item-table, #jewel-table) .item-cell { min-width: 0; padding: 12px; }
  #item-table .item-row-sub { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; margin-top: 4px; font-size: var(--fs-xs); line-height: 1.4; color: var(--text-muted); }
  #item-table .item-row-stat { color: var(--text-strong); font-weight: 600; }
  #item-table .item-row-stat::after { content: " · "; content: " · " / ""; color: var(--text-muted); font-weight: 400; }   /* stat and classes share the two clamped lines */
}

/* --- Item / skill pages: related links (ux#2) --- */
.db-related-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 300px), 1fr)); gap: var(--sp-2); margin: 0; padding: 0; list-style: none; }
.db-related-list > li { display: flex; min-width: 0; }
.db-related-link {
  flex: 1 1 auto;
  display: flex;
  align-items: center;
  gap: 12px;
  min-width: 0;
  min-height: 52px;
  padding: 8px 12px;
  border: 1px solid var(--border-strong);
  border-radius: var(--r-md);
  background: linear-gradient(180deg, rgba(255,196,140,.05), rgba(255,196,140,.015)), var(--surface-1);
  box-shadow: var(--bevel);
  color: inherit;
  text-decoration: none;
  transition: border-color var(--dur-fast), box-shadow var(--dur-fast);
}
.db-related-link:has(.item-icon) { padding-left: 8px; }
.db-related-link:hover { border-color: var(--gold-line); box-shadow: var(--bevel), var(--glow-gold); }
.db-related-text { display: grid; gap: 2px; min-width: 0; }
.db-related-name { color: var(--accent-text); font-size: var(--fs-sm); font-weight: 700; line-height: 1.3; overflow-wrap: anywhere; }
.db-related-link:hover .db-related-name { color: var(--accent-text-hover); text-decoration: underline; }
.db-related-sub { color: var(--text-muted); font-size: var(--fs-xs); line-height: 1.4; }
.db-related-more { margin: var(--sp-4) 0 0; font-size: var(--fs-sm); }
.db-related-more a { color: var(--accent-text); font-weight: 600; text-decoration: none; }
.db-related-more a:hover { color: var(--accent-text-hover); text-decoration: underline; }
.item-detail-note { margin: 0; font-size: var(--fs-sm); color: var(--text-muted); }

/* Item and skill page headers (art#8: one detail template): the media frame is a 3:4 display case, 84px on
   phones and up to 168px from 900px. Items: the sprite, contained (ui.css crops header media to cover); the 100%
   track gives it a definite box, so its max-height works at every width. Skills (no skill icon art): the
   portrait of the first eligible class fills the case, so the reader sees at a glance whose skill it is. */
:is(.item-details, .skill-details) .page-header__media { display: grid; grid-template-rows: 100%; grid-template-columns: 100%; place-items: center; background: radial-gradient(circle at 50% 42%, rgba(245,201,80,.16), rgba(0,0,0,0) 70%), #0d0907; }
:is(.item-details, .skill-details) .page-header__media img { width: auto; height: auto; max-width: 78%; max-height: 88%; object-fit: contain; }
.skill-details .page-header__media img { width: 100%; height: 100%; max-width: none; max-height: none; object-fit: cover; object-position: 50% 18%; }
/* art#4: the portrait takes the ember grade every other class portrait wears (home roster, /classes, class tiles,
   character hero: ui.css .class-tile__media::after), instead of its raw cold purple sky. Off in forced colours and
   high-contrast mode, like the tile grade. */
.skill-details .page-header__media { position: relative; }
.skill-details .page-header__media::after { content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none; border-radius: inherit; background: radial-gradient(62% 44% at 50% 50%, rgba(107,36,16,0) 52%, #6b2410 100%), linear-gradient(180deg, #6b2410 0%, rgba(107,36,16,0) 34%); mix-blend-mode: color; opacity: .92; }
.skill-details .page-header__media:not(:has(img))::after { content: none; }
@media (forced-colors: active), (prefers-contrast: more) {
  .skill-details .page-header__media::after { display: none; }
}
:is(.item-details, .skill-details) .page-header.has-media .page-header__media { width: 84px; aspect-ratio: 3 / 4; }
@media (min-width: 640px) {
  :is(.item-details, .skill-details) .page-header.has-media .page-header__media { width: clamp(84px, 10vw, 104px); }
}
@media (min-width: 900px) {
  :is(.item-details, .skill-details) .page-header.has-media .page-header__media { width: clamp(120px, 11vw, 168px); }
}
