@font-face {
    font-family: 'Final Fantasy I';
    src: url('/slothsoft@final-fantasy/i/font') format('truetype');
    font-style: normal;
    font-weight: 400;
    font-display: swap;
}

/* Apply to a component, not the host page. Override --ff-scale on that root. */
.ff-ui {
    --ff-font-size: 8px;
    --ff-sprite-size: 24px;
    --ff-scale: 1;
    --ff-pose: 0;
    --ff-icon-index: 0;
    --ff-unit: calc(var(--ff-font-size) * var(--ff-scale));
    --ff-border: calc(var(--ff-unit) / 8);
    --ff-sprite-height: calc(var(--ff-sprite-size) * var(--ff-scale));
    --ff-sprite-width: calc(var(--ff-sprite-height) * 2 / 3);
    /* Full 2C02 RGB approximation, matching NesSpriteSheet. ROMs store indices,
       not RGB values. Duplicate black indices share one named color.
       Palette primitives remain independent of the semantic tokens below. */
    --ff-gray: #7c7c7c; /* $00 */
    --ff-blue: #0000fc; /* $01 */
    --ff-dark-blue: #0000bc; /* $02 */
    --ff-indigo: #4428bc; /* $03 */
    --ff-purple: #940084; /* $04 */
    --ff-wine: #a80020; /* $05 */
    --ff-dark-red: #a81000; /* $06 */
    --ff-rust: #881400; /* $07 */
    --ff-brown: #503000; /* $08 */
    --ff-forest-green: #007800; /* $09 */
    --ff-dark-green: #006800; /* $0A */
    --ff-pine-green: #005800; /* $0B */
    --ff-dark-teal: #004058; /* $0C */
    --ff-black: #000000; /* $0D, $0E, $0F, $1D, $1E, $1F, $2E, $2F, $3E, $3F */
    --ff-silver: #bcbcbc; /* $10 */
    --ff-azure: #0078f8; /* $11 */
    --ff-royal-blue: #0058f8; /* $12 */
    --ff-violet: #6844fc; /* $13 */
    --ff-magenta: #d800cc; /* $14 */
    --ff-rose: #e40058; /* $15 */
    --ff-red: #f83800; /* $16 */
    --ff-orange: #e45c10; /* $17 */
    --ff-ochre: #ac7c00; /* $18 */
    --ff-bright-green: #00b800; /* $19 */
    --ff-green: #00a800; /* $1A */
    --ff-emerald: #00a844; /* $1B */
    --ff-teal: #008888; /* $1C */
    --ff-off-white: #f8f8f8; /* $20 */
    --ff-sky-blue: #3cbcfc; /* $21 */
    --ff-cornflower-blue: #6888fc; /* $22 */
    --ff-lavender: #9878f8; /* $23 */
    --ff-orchid: #f878f8; /* $24 */
    --ff-pink: #f85898; /* $25 */
    --ff-salmon: #f87858; /* $26 */
    --ff-apricot: #fca044; /* $27 */
    --ff-gold: #f8b800; /* $28 */
    --ff-lime: #b8f818; /* $29 */
    --ff-leaf-green: #58d854; /* $2A */
    --ff-mint: #58f898; /* $2B */
    --ff-turquoise: #00e8d8; /* $2C */
    --ff-dark-gray: #787878; /* $2D */
    --ff-white: #fcfcfc; /* $30 */
    --ff-pale-blue: #a4e4fc; /* $31 */
    --ff-periwinkle: #b8b8f8; /* $32 */
    --ff-pale-lavender: #d8b8f8; /* $33 */
    --ff-pale-pink: #f8b8f8; /* $34 */
    --ff-blush: #f8a4c0; /* $35 */
    --ff-peach: #f0d0b0; /* $36 */
    --ff-cream: #fce0a8; /* $37 */
    --ff-sand: #f8d878; /* $38 */
    --ff-pale-lime: #d8f878; /* $39 */
    --ff-pale-green: #b8f8b8; /* $3A */
    --ff-pale-mint: #b8f8d8; /* $3B */
    --ff-cyan: #00fcfc; /* $3C */
    --ff-pale-rose: #f8d8f8; /* $3D */
    --ff-foreground: var(--ff-white);
    --ff-background: var(--ff-blue);
    --ff-frame: var(--ff-white);
    --ff-frame-shade: var(--ff-gray);
    --ff-frame-shadow: var(--ff-black);
    --ff-heading: var(--ff-pale-blue);
    --ff-interaction: var(--ff-cyan);
    --ff-link: var(--ff-gold);
    --ff-link-visited: var(--ff-ochre);
    --ff-link-hover: var(--ff-interaction);
    --ff-link-active: var(--ff-white);
    font-family: 'Final Fantasy I', monospace;
    font-size: var(--ff-unit);
    font-style: normal;
    font-weight: 400;
    font-synthesis: none;
    line-height: 150%;
    letter-spacing: 0;
    text-shadow: calc(1px * var(--ff-scale)) calc(1px * var(--ff-scale)) 0 var(--ff-black);
    color: var(--ff-foreground);
    background: var(--ff-background);
    min-width: 0;
    max-width: 100%;
}

.ff-ui, .ff-ui * {
    box-sizing: border-box;
}

.ff-ui :where(*) {
    font-family: inherit;
    font-size: inherit;
    font-style: inherit;
    font-weight: inherit;
    line-height: inherit;
    letter-spacing: inherit;
    text-shadow: inherit;
    color: inherit;
}

.ff-ui.ff-panel, .ff-ui .ff-panel, .ff-ui.ff-panel > legend, .ff-ui .ff-panel > legend {
    width: fit-content;
    max-width: 100%;
    border: var(--ff-border) solid var(--ff-frame);
    border-radius: calc(var(--ff-border) * 2);
    box-shadow: inset 0 0 0 var(--ff-border) var(--ff-frame-shade),
    0 0 0 var(--ff-border) var(--ff-frame-shade),
    0 0 0 calc(var(--ff-border) * 2) var(--ff-frame-shadow);
    background: var(--ff-background);
    color: var(--ff-foreground);
    padding: 1em;
    min-inline-size: 0;
    margin: 0;
}

.ff-ui :where(h1, h2, h3, h4, p, ul) {
    margin-block: .5em;
}

.ff-ui :where(h1, h2, h3, h4, p) {
    padding: 0;
    text-align: left;
}

.ff-ui a:any-link {
    text-decoration: none;
    text-shadow: inherit;
}

.ff-ui a:link {
    color: var(--ff-link);
}

.ff-ui a:visited {
    color: var(--ff-link-visited);
}

.ff-ui a:hover, .ff-ui a:focus-visible {
    color: var(--ff-link-hover);
}

.ff-ui a:active {
    color: var(--ff-link-active);
}

.ff-ui table {
    width: auto;
    border-spacing: 0;
    border-collapse: collapse;
    border: none;
}

.ff-ui :where(table, caption, thead, tbody, tfoot, tr, th, td) {
    background: var(--ff-background);
    color: var(--ff-foreground);
    box-shadow: none;
    border-radius: 0;
}

.ff-ui caption {
    text-align: left;
    padding: 0 0 1em;
}

.ff-ui th, .ff-ui td {
    text-align: left;
    vertical-align: top;
    padding: 0;
    border: none;
    border-bottom: var(--ff-border) solid var(--ff-frame-shade);
}

.ff-ui th:not(:last-child), .ff-ui td:not(:last-child) {
    padding-inline-end: 2ch;
}

.ff-ui thead th {
    text-align: center;
    vertical-align: middle;
    color: var(--ff-heading);
}

.ff-ui tbody th {
    white-space: nowrap;
}

.ff-ui :where(input, select, option, button, textarea),
.ff-ui ::file-selector-button {
    font: inherit;
    text-shadow: inherit;
    color: var(--ff-foreground);
    background: var(--ff-background);
}

.ff-ui :where(input, select, button, textarea),
.ff-ui ::file-selector-button {
    width: fit-content;
    max-width: 100%;
    border: var(--ff-border) solid var(--ff-frame);
    border-radius: 0;
    padding: .5em;
}

.ff-ui select {
    display: block;
    width: fit-content;
    min-width: 0;
    margin: 0;
    /* Reserve the border so interaction never changes control geometry. */
    border-color: transparent;
}

.ff-ui :is(input, select, button, textarea):enabled:is(:hover, :active, :focus, :focus-within, :open),
.ff-ui input[type="file"]:enabled:is(:hover, :active, :focus, :focus-within)::file-selector-button {
    color: var(--ff-interaction);
    border-color: var(--ff-interaction);
}

.ff-ui button, .ff-ui ::file-selector-button {
    cursor: pointer;
    padding-inline: 1em;
}

.ff-ui input[type="file"] {
    max-width: 100%;
    border: none;
    padding: 0;
}

.ff-ui input[type="checkbox"] {
    appearance: none;
    display: inline-grid;
    place-content: center;
    width: 1em;
    height: 1em;
    padding: 0;
    margin: 0 .5em 0 0;
    vertical-align: -.125em;
}

.ff-ui input[type="checkbox"]:checked::after {
    content: 'X';
    line-height: 1;
}

.ff-ui legend {
    padding-inline: .5em;
    color: var(--ff-foreground);
    background: var(--ff-background);
}

.ff-ui :focus-visible {
    outline: var(--ff-border) solid var(--ff-interaction);
    outline-offset: var(--ff-border);
}

.ff-ui select:focus-visible {
    /* The visible frame is the keyboard focus indicator for selects. */
    outline: none;
}

.ff-ui .ff-class-sprite {
    --ff-sprite: none;
    display: block;
    flex: none;
    background-image: var(--ff-sprite);
    width: var(--ff-sprite-width);
    height: var(--ff-sprite-height);
    background-size: calc(var(--ff-sprite-width) * 8) var(--ff-sprite-height);
    background-position: calc(-1 * var(--ff-pose, 0) * var(--ff-sprite-width)) 0;
    background-repeat: no-repeat;
    image-rendering: pixelated;
}

.ff-ui .ff-class-sprite[data-allowed="false"] {
    filter: grayscale(0.5) opacity(0.5) brightness(0.75);
}

/* Layout inputs reset on each utility so nested layouts do not inherit tracks/gaps. */
.ff-contain {
    min-inline-size: 0;
    max-inline-size: 100%;
    contain: inline-size;
}

.ff-ui.ff-panel {
    margin-block: 1em;
}

.ff-ui.ff-panel > legend, .ff-ui .ff-panel > legend {
    padding: .5em;
    margin-inline-start: calc(-1em - var(--ff-border));
}

.ff-ui.ff-fit, .ff-ui .ff-fit {
    width: fit-content;
    max-width: 100%;
    min-inline-size: 0;
}

.ff-ui.ff-row, .ff-ui .ff-row {
    --ff-gap: .5em;
    --ff-wrap: nowrap;
    display: flex;
    align-items: center;
    flex-wrap: var(--ff-wrap);
    gap: var(--ff-gap);
    min-inline-size: 0;
}

.ff-ui.ff-grid, .ff-ui .ff-grid {
    --ff-columns: repeat(2, max-content);
    --ff-gap: 1em;
    --ff-row-gap: var(--ff-gap);
    --ff-column-gap: var(--ff-gap);
    display: grid;
    grid-template-columns: var(--ff-columns);
    gap: var(--ff-row-gap) var(--ff-column-gap);
    min-inline-size: 0;
}

.ff-ui.ff-scroll, .ff-ui .ff-scroll {
    --ff-scroll-padding: 0;
    overflow-x: auto;
    min-inline-size: 0;
    padding: var(--ff-scroll-padding);
}

.ff-ui td.ff-number {
    text-align: right;
}

.ff-ui .ff-prose {
    --ff-measure: 44ch;
    max-width: var(--ff-measure);
    white-space: normal;
}

.ff-ui .ff-prose p {
    margin: 0;
}

.ff-ui .ff-inline-list {
    list-style: none;
    margin: 0;
    padding: 0;
}

.ff-ui .ff-inline-list li {
    display: inline;
}

.ff-ui .ff-inline-list li:not(:last-child)::after {
    content: ', ';
}

.ff-ui .ff-class-sprite.ff-portrait {
    height: calc(var(--ff-sprite-height) / 2);
}

.ff-ui select.ff-select {
    --ff-option-width: 10ch;
    /* Text width, one ch padding, two ch native arrow, and both borders. */
    width: calc(var(--ff-option-width) + 3ch + var(--ff-border) * 2);
    height: 1.5em;
    padding: 0 .5em;
    line-height: 1;
}

.ff-ui input.ff-equipped {
    border: none;
    margin: 0;
    width: 1em;
    height: 1.5em;
    background: transparent;
    cursor: pointer;
}

.ff-ui input.ff-equipped::after, .ff-ui input.ff-equipped:checked::after {
    content: 'E';
    line-height: 150%;
}

.ff-ui input.ff-equipped:not(:checked)::after {
    opacity: .25;
}

/* Compatibility helpers: retained for existing consumers; use the utilities above. */
.ff-ui.ff-table {
    overflow-x: auto;
}

.ff-ui .ff-classes {
    display: inline-grid;
    grid-template-columns: repeat(6, var(--ff-sprite-width));
    gap: calc(var(--ff-border) * 2);
}

.ff-ui .ff-class-entry {
    position: relative;
}

.ff-ui .ff-class-tooltip {
    display: none;
    position: absolute;
    bottom: 100%;
    right: 0;
    z-index: 1;
    padding: .5em;
    color: var(--ff-foreground);
    background: var(--ff-background);
    border: var(--ff-border) solid var(--ff-frame);
    white-space: nowrap;
    pointer-events: none;
}

.ff-ui .ff-class-entry:hover .ff-class-tooltip,
.ff-ui .ff-class-entry:focus .ff-class-tooltip {
    display: block;
}

.ff-ui .ff-item-icon {
    display: inline-block;
    width: var(--ff-unit);
    height: var(--ff-unit);
    background-image: url('/slothsoft@final-fantasy/i/gfx/items');
    background-size: calc(var(--ff-unit) * 14) var(--ff-unit);
    background-position: calc(-1 * var(--ff-icon-index, 0) * var(--ff-unit)) 0;
    background-repeat: no-repeat;
    image-rendering: pixelated;
}

/* Native visibility wins over layout utilities and compatibility helpers. */
.ff-ui[hidden], .ff-ui [hidden] {
    display: none;
}
