/* Chrome around the board: the pieces every JS module already creates but
   that tokens/layout/board.css never styled -- the live region, the modal
   host, the note editor and lists, the settings form, the hint strip, and the
   retry panels. Kept in its own file because tokens.css is parsed by the
   contrast gate and board.css/layout.css are asserted against by source-level
   regex tests; adding here keeps those checks unambiguous. */

/* The announcer sets this class on its aria-live region. Without a definition
   the region renders as ordinary visible text, so every announcement ("후보
   입력 모드 켜짐", "메모가 저장되었습니다") would appear on screen. Clip
   rather than display:none -- a hidden element is dropped from the
   accessibility tree and would never be announced at all. */
.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

/* §10's 48px control floor (L3), applied where the buttons actually are.
   The modules that build them are not all in this change's scope, so the
   floor is expressed as a rule over the app's button hosts rather than as a
   class each module has to remember to add. */
.app-shell-header button,
.digit-bar button,
.notes-list button,
.note-target-selector button,
.note-editor button,
.retry-panel button,
[role="dialog"] button,
.control {
    min-inline-size: var(--control-floor);
    min-block-size: var(--control-floor);
    padding: 0 12px;
    font: inherit;
    color: var(--fg-body);
    background: var(--bg-cell);
    border: 1px solid var(--line);
    border-radius: 6px;
    cursor: pointer;
}

.app-shell-header button:focus-visible,
.digit-bar button:focus-visible,
.notes-list button:focus-visible,
.note-target-selector button:focus-visible,
.note-editor button:focus-visible,
.retry-panel button:focus-visible,
[role="dialog"] button:focus-visible {
    outline: 2px solid var(--focus);
    outline-offset: 2px;
}

/* ------------------------------------------------------------- app shell */
.app-shell-header-host {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 8px;
}

.app-shell-header {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

.board-area {
    display: flex;
    justify-content: center;
    padding: 8px;
}

.controls-area,
.notes-area {
    padding: 0 8px;
}

/* Completion is signalled by a text badge, not by color alone (V4-05). */
.app-shell-header-host[data-state="solved"]::after {
    content: "완성";
    align-self: flex-start;
    padding: 4px 10px;
    border-radius: 999px;
    color: var(--fg-given);
    background: var(--bg-cell-selected);
}

.hint-strip {
    padding: 8px;
    color: var(--fg-candidate);
    background: var(--bg-cell-peer);
    border-radius: 6px;
}

.hint-strip::before {
    content: "방향키로 이동하고 숫자키로 입력하세요. ? 키로 도움말을 엽니다.";
}

/* ------------------------------------------------------------- digit bar */
/* layout.css sizes .digit-bar as a single 60px row of nine digits. The pencil
   and memo controls make eleven children in a nine-column grid, so the bar
   needs a second row; the fixed height would otherwise clip it. */
.digit-bar {
    block-size: auto;
    grid-auto-rows: minmax(var(--control-floor), auto);
    row-gap: 6px;
}

.digit-bar[data-visibility="collapsed"] {
    display: none;
}

.digit-bar button[data-active="1"] {
    background: var(--bg-cell-digit);
    border-color: var(--focus);
    border-width: 2px;
}

/* ------------------------------------------------------------ dialog host */
.dialog-host:empty {
    display: none;
}

[role="dialog"] {
    position: fixed;
    inset-block-start: 50%;
    inset-inline-start: 50%;
    transform: translate(-50%, -50%);
    z-index: 10;
    display: flex;
    flex-direction: column;
    gap: 12px;
    inline-size: min(90vw, 420px);
    max-block-size: 80dvh;
    overflow-y: auto;
    padding: 16px;
    color: var(--fg-body);
    background: var(--bg-cell);
    border: 2px solid var(--line);
    border-radius: 10px;
}

[role="dialog"] table {
    border-collapse: collapse;
    inline-size: 100%;
}

[role="dialog"] td {
    padding: 4px 8px;
    border-bottom: 1px solid var(--bg-cell-peer);
}

/* ------------------------------------------------------- notes and editor */
.note-editor,
.note-target-selector,
.notes-list {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    padding: 12px;
    background: var(--bg-cell);
    border: 1px solid var(--line);
    border-radius: 8px;
}

.note-editor textarea {
    flex: 1 1 100%;
    min-block-size: 96px;
    padding: 8px;
    font: inherit;
    color: var(--fg-body);
    background: var(--bg-page);
    border: 1px solid var(--line);
    border-radius: 6px;
    resize: vertical;
}

.notes-list {
    flex-direction: column;
}

.notes-list button {
    display: flex;
    gap: 12px;
    justify-content: flex-start;
    text-align: start;
}

/* ------------------------------------------------------- settings and share */
.settings-form {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.settings-form label {
    display: flex;
    gap: 8px;
    align-items: center;
}

.settings-form fieldset {
    display: flex;
    flex-direction: column;
    gap: 8px;
    margin: 0;
    padding: 8px;
    border: 1px solid var(--line);
    border-radius: 6px;
}

.share-fallback input {
    inline-size: 100%;
    padding: 8px;
    font: inherit;
    color: var(--fg-body);
    background: var(--bg-page);
    border: 1px solid var(--line);
}

/* ------------------------------------------------------------ retry panel */
.retry-panel {
    display: flex;
    flex-direction: column;
    gap: 12px;
    align-items: flex-start;
    margin: 16px;
    padding: 16px;
    background: var(--bg-cell-conflict);
    border: 1px solid var(--fg-conflict);
    border-radius: 8px;
}

.retry-panel button[data-highlight="1"] {
    border-color: var(--focus);
    border-width: 2px;
}

.retry-detail {
    margin: 0;
    color: var(--fg-candidate);
    font-size: 0.875rem;
}

/* The inert skeleton main.js paints before app.js loads. It has no content of
   its own, so it only reserves height to stop the first paint from jumping. */
[data-state="skeleton"] {
    min-block-size: 50dvh;
}
