/* ============================================
   じゃんけんゲーム（本格版）のスタイル
   配色は手の画像（グー＝青・チョキ＝黄・パー＝赤）から採っている。
   ============================================ */

/* カスケードレイヤー。層の順番を先に宣言しておくと、後ろの層ほど優先される（utilities が最優先）。
   層どうしの強さは詳細度より先に決まるので、セレクタを強くしたり書く順番に気を配ったりせずに済む。
   同じ層の中では、いつもどおり詳細度と書いた順で決まる */
@layer reset, tokens, base, layout, components, sections, utilities;

/* ============================================
   reset — ブラウザごとの初期スタイルの差をなくす
   :where() の中のセレクタは詳細度が 0 になり、後から書いたどのスタイルにも負ける
   ============================================ */
@layer reset {
  :where(*, *::before, *::after) { box-sizing: border-box; }
  :where(body, h1, h2, h3, p, figure, dl, dd, ol) { margin: 0; }
  /* class の付いた一覧（履歴など）だけ、番号と字下げを消す */
  :where(ol[class]) { padding: 0; list-style: none; }
  :where(img, svg) { display: block; max-inline-size: 100%; }
  :where(button, input) { font: inherit; color: inherit; }
}

/* ============================================
   tokens — 色・大きさ・動き
   -- で始まる名前はカスタムプロパティ（CSS 変数）で、var(--blue) のように呼び出す。
   色や大きさを 1 か所で決めておけば、ダークモードではここを差し替えるだけで済む
   ============================================ */
@layer tokens {
  :root {
    color-scheme: light;

    /* 素材の色 */
    --blue:   #70abe2;  /* グー */
    --yellow: #ffdd00;  /* チョキ */
    --red:    #fe4f4f;  /* パー */
    --skin:   #ffe2d3;  /* 手の肌色 */
    --ink:    #3a3434;  /* 手の輪郭線の色を濃くしたもの */

    /* 役割ごとの色。color-mix() は 2 色を指定の割合で混ぜる。
       たとえば --muted は、文字色に背景色を 32% 混ぜた控えめな色になる */
    --paper:    #fdf8f4;
    --surface:  #ffffff;
    --text:     var(--ink);
    --muted:    color-mix(in srgb, var(--ink) 68%, var(--paper));
    --line:     rgb(86 79 79 / .16);
    --focus:    #2c6aa3;
    --danger:   #b53434;  /* パーの赤を、文字として読める濃さにしたもの */
    --win-bg:   color-mix(in srgb, var(--yellow) 30%, var(--surface));
    --lose-bg:  color-mix(in srgb, var(--red) 18%, var(--surface));
    --draw-bg:  color-mix(in srgb, var(--blue) 22%, var(--surface));

    --font-round: "Hiragino Maru Gothic ProN", "Hiragino Sans", "Noto Sans JP", system-ui, sans-serif;
    --wrap: 64rem;
    --gutter: clamp(1rem, 4vw, 2rem);
    --radius-s: 10px;
    --radius-m: 20px;
    --shadow-s: 0 4px 12px -6px rgb(86 79 79 / .3);
    --shadow-m: 0 16px 40px -18px rgb(86 79 79 / .4);
    --ease: cubic-bezier(.22, .68, .32, 1);
  }

  /* ダークモードは地色と文字色だけを入れ替え、素材の三色はそのまま使う */
  @media (prefers-color-scheme: dark) {
    :root {
      color-scheme: dark;
      --paper:   #1f1c1c;
      --surface: #2b2727;
      --text:    #f3ece8;
      --muted:   color-mix(in srgb, #f3ece8 70%, #1f1c1c);
      --line:    rgb(243 236 232 / .14);
      --focus:   #9cc6ee;
      --danger:  #ff8a8a;
      --win-bg:  color-mix(in srgb, var(--yellow) 22%, var(--surface));
      --lose-bg: color-mix(in srgb, var(--red) 24%, var(--surface));
      --draw-bg: color-mix(in srgb, var(--blue) 24%, var(--surface));
      --shadow-s: 0 4px 12px -6px rgb(0 0 0 / .6);
      --shadow-m: 0 16px 40px -18px rgb(0 0 0 / .7);
    }
  }
}

/* ============================================
   base
   ============================================ */
@layer base {
  /* ヘッダー・本文・フッターの 3 段。1fr の本文が残りの高さをすべて使うので、
     中身が少なくてもフッターは画面の下端に来る。
     dvh は、スマートフォンのアドレスバーが出入りしても、実際に見えている高さに合わせた単位 */
  body {
    display: grid;
    grid-template-rows: auto 1fr auto;
    min-block-size: 100dvh;
    font-family: var(--font-round);
    line-height: 1.6;
    color: var(--text);
    background-color: var(--paper);
    /* 三色の水玉をうっすら敷く */
    background-image:
      radial-gradient(circle at 8% 12%, color-mix(in srgb, var(--blue) 18%, transparent) 0 9rem, transparent 9rem),
      radial-gradient(circle at 94% 30%, color-mix(in srgb, var(--yellow) 16%, transparent) 0 7rem, transparent 7rem),
      radial-gradient(circle at 12% 92%, color-mix(in srgb, var(--red) 12%, transparent) 0 8rem, transparent 8rem);
    background-attachment: fixed;
  }

  a { color: var(--focus); text-underline-offset: .2em; }

  :focus-visible {
    outline: 3px solid var(--focus);
    outline-offset: 3px;
  }
}

/* ============================================
   layout
   ============================================ */
@layer layout {
  /* min() は小さいほうを採る。狭い画面では左右に余白を残し、広い画面では 64rem で止めて中央に置く */
  .site-header,
  .layout,
  .site-footer {
    inline-size: min(100% - var(--gutter) * 2, var(--wrap));
    margin-inline: auto;
  }

  .site-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    /* clamp(最小, 理想, 最大)。画面の高さの 2% を理想に、.6rem〜1rem の間で変わる */
    padding-block: clamp(.6rem, 2dvh, 1rem);
  }

  /* 広い画面では対戦と成績を左右に並べる。
     カードは行いっぱいに伸びるので、2 枚の高さが揃い、フッターとの間に余白が残らない */
  .layout {
    display: grid;
    gap: var(--gutter);
    padding-block-end: clamp(1rem, 3dvh, 2rem);

    /* minmax(0, …) にすると、中身が長くても列がはみ出さず、1.15 : 1 の比率を保つ */
    @media (width >= 60rem) {
      grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
    }
  }

  .site-footer {
    display: grid;
    gap: .25rem;
    padding-block: 1.5rem 2rem;
    font-size: .8rem;
    color: var(--muted);
    text-align: center;
    border-block-start: 1px solid var(--line);
  }
}

/* ============================================
   components — 再利用する部品
   ============================================ */
@layer components {
  .icon {
    flex: none;
    inline-size: 1.25em;
    block-size: 1.25em;
  }

  /* ---- ボタン ---- */
  .button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: .5rem;
    min-block-size: 2.75rem;
    padding: .5rem 1.25rem;
    font-weight: 700;
    color: var(--text);
    background-color: var(--surface);
    border: 2px solid var(--line);
    border-radius: 999px;
    cursor: pointer;
    /* translate は transform とは別のプロパティ。ほかの変形（scale など）と打ち消し合わない */
    transition: translate .2s var(--ease), box-shadow .2s var(--ease), background-color .2s;

    /* 押せないとき（:disabled）は浮き上がらせない */
    &:hover:not(:disabled) {
      translate: 0 -2px;
      box-shadow: var(--shadow-s);
    }

    &:active:not(:disabled) { translate: 0 0; }

    &:disabled {
      cursor: not-allowed;
      opacity: .55;
    }
  }

  .button-primary {
    color: var(--ink);
    background-color: var(--blue);
    border-color: transparent;

    &:hover:not(:disabled) { background-color: color-mix(in srgb, var(--blue) 85%, var(--ink)); }
  }

  .button-danger {
    color: var(--danger);
    border-color: color-mix(in srgb, var(--danger) 45%, transparent);
  }

  .icon-button {
    display: grid;
    place-items: center;
    inline-size: 3rem;
    block-size: 3rem;
    background-color: var(--surface);
    border: 2px solid var(--line);
    border-radius: 50%;
    box-shadow: var(--shadow-s);
    cursor: pointer;

    .icon { inline-size: 1.5rem; block-size: 1.5rem; }
  }

  /* ---- 確認ダイアログ ---- */
  .confirm {
    inline-size: min(100% - 2rem, 26rem);
    padding: 1.5rem;
    color: var(--text);
    background-color: var(--surface);
    border: none;
    border-radius: var(--radius-m);
    box-shadow: var(--shadow-m);

    /* ::backdrop は、showModal() で開いたダイアログの後ろに敷かれる幕 */
    &::backdrop { background-color: rgb(31 28 28 / .55); }

    form { display: grid; gap: 1rem; }
  }

  .confirm-title { font-size: 1.15rem; text-wrap: balance; }

  .confirm-actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: .75rem;
  }

  /* ---- 更新のお知らせ ----
     画面の下に固定し、fit-content ＋ margin-inline: auto で、中身の幅のまま中央に置く */
  .update-bar {
    position: fixed;
    inset-block-end: 1rem;
    inset-inline: 1rem;
    z-index: 10;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: .75rem 1rem;
    inline-size: fit-content;
    margin-inline: auto;
    padding: .75rem 1rem .75rem 1.25rem;
    background-color: var(--surface);
    border: 2px solid var(--blue);
    border-radius: var(--radius-m);
    box-shadow: var(--shadow-m);

    /* display を指定すると hidden 属性が効かなくなるので、hidden のときは明示的に消す */
    &[hidden] { display: none; }
  }
}

/* ============================================
   sections — このページ固有の部分
   ============================================ */
@layer sections {
  /* ---- ヘッダー ---- */
  .site-title {
    display: flex;
    align-items: center;
    gap: .5rem;
    font-size: clamp(1.15rem, 5vw, 1.9rem);
    white-space: nowrap;

    /* 三色の丸をロゴ代わりに並べる。radial-gradient で丸を 3 つ描き、画像を使わずに済ませる */
    &::before {
      content: "";
      inline-size: 2.2em;
      block-size: .7em;
      background:
        radial-gradient(circle at 16.6% 50%, var(--blue) 0 .35em, transparent .36em),
        radial-gradient(circle at 50% 50%, var(--yellow) 0 .35em, transparent .36em),
        radial-gradient(circle at 83.3% 50%, var(--red) 0 .35em, transparent .36em);
    }
  }

  .header-actions {
    display: flex;
    align-items: center;
    gap: .6rem;
  }

  /* 「成績」ボタンは、成績を横に並べられない狭い画面だけに出す */
  .record-toggle {
    min-block-size: 3rem;
    padding-inline: .85rem;
    white-space: nowrap;
    box-shadow: var(--shadow-s);

    @media (width >= 60rem) { display: none; }
  }

  /* 音の ON/OFF：aria-pressed の値でアイコンを切り替える */
  [data-action="toggle-sound"] {
    &[aria-pressed="true"] .icon-off,
    &[aria-pressed="false"] .icon-on { display: none; }

    &[aria-pressed="false"] { color: var(--muted); }
  }

  /* ---- 対戦 ---- */
  /* 画面の高さ（dvh）に合わせて余白や大きさを縮め、小さなスマートフォンでも 1 画面に収める。
     カードが縦に伸びたときは、align-content: space-evenly で、余った高さを中身の上下と間に均等に配る */
  .game {
    display: grid;
    align-content: space-evenly;
    gap: clamp(.6rem, 2dvh, 1.25rem);
    padding: clamp(1rem, 4vw, 2.25rem);
    text-align: center;
    background-color: var(--surface);
    border-radius: var(--radius-m);
    box-shadow: var(--shadow-m);
  }

  /* 狭い画面だけに出す、勝敗の小さな集計 */
  .score-strip {
    display: flex;
    justify-content: center;
    gap: .25rem 1.25rem;
    font-size: .85rem;
    color: var(--muted);

    span {
      display: inline-flex;
      align-items: center;
      gap: .35rem;

      /* 勝敗の色の丸を添える */
      &::before {
        content: "";
        inline-size: .6rem;
        block-size: .6rem;
        background-color: var(--dot);
        border-radius: 50%;
      }
    }

    /* --dot の値だけを項目ごとに変え、同じ ::before の指定で丸の色を塗り分ける */
    [data-result="win"]  { --dot: var(--yellow); }
    [data-result="lose"] { --dot: var(--red); }
    [data-result="draw"] { --dot: var(--blue); }

    b {
      font-size: 1.1rem;
      color: var(--text);
      /* 数字の幅を揃え、桁が変わっても横に揺れないようにする */
      font-variant-numeric: tabular-nums;
    }

    @media (width >= 60rem) { display: none; }
  }

  .opponent {
    display: grid;
    justify-items: center;
    gap: .4rem;
  }

  /* min(42vw, 24dvh) で画面の幅と高さの窮屈なほうに合わせ、clamp で 6.5rem〜20rem に収める */
  .opponent-stage {
    --size: clamp(6.5rem, min(42vw, 24dvh), 20rem);
    display: grid;
    place-items: center;
    inline-size: var(--size);
    block-size: var(--size);
    background-color: color-mix(in srgb, var(--skin) 55%, var(--surface));
    border: 6px solid var(--surface);
    border-radius: 50%;
    /* ぼかしのない影（0 0 0 3px）を縁取りとして使う。border と違い、太さを変えても円の大きさが変わらない */
    box-shadow: 0 0 0 3px var(--line), var(--shadow-s);
    transition: box-shadow .3s var(--ease);
  }

  .opponent-hand {
    inline-size: 88%;
    block-size: auto;
  }

  .opponent-name {
    font-weight: 700;
    color: var(--muted);

    /* 高さの足りない画面（Safari で開いた小さな iPhone など）では、読み上げ専用にして場所を空ける */
    @media (height < 600px) {
      position: absolute;
      inline-size: 1px;
      block-size: 1px;
      overflow: hidden;
      clip-path: inset(50%);
    }
  }

  /* JavaScript が付けた data-state・data-result の値で、見た目を切り替える */
  /* シャッフル中は手を揺らす */
  .game[data-state="playing"] .opponent-hand {
    animation: shake .5s ease-in-out infinite;
  }

  /* 結果が出たら、勝敗の色の輪で囲み、少し弾ませる */
  .game[data-state="result"] .opponent-stage {
    animation: pop .45s var(--ease);
  }
  .game[data-result="win"]  .opponent-stage { box-shadow: 0 0 0 5px var(--yellow), var(--shadow-s); }
  .game[data-result="lose"] .opponent-stage { box-shadow: 0 0 0 5px var(--red), var(--shadow-s); }
  .game[data-result="draw"] .opponent-stage { box-shadow: 0 0 0 5px var(--blue), var(--shadow-s); }

  .message {
    display: grid;
    place-items: center;
    min-block-size: 3rem;
    padding: .4rem 1rem;
    font-size: clamp(1rem, 3.8vw, 1.25rem);
    font-weight: 700;
    text-wrap: balance;
    /* 日本語を文節の切れ目で折り返す（対応ブラウザのみ。「は／じめる」のような分かれ方を防ぐ） */
    word-break: auto-phrase;
    background-color: color-mix(in srgb, var(--ink) 5%, var(--surface));
    border-radius: var(--radius-s);
    transition: background-color .3s;

    /* & を後ろに書くと「.game が win のときの .message」という意味になる */
    .game[data-result="win"] &  { background-color: var(--win-bg); }
    .game[data-result="lose"] & { background-color: var(--lose-bg); }
    .game[data-result="draw"] & { background-color: var(--draw-bg); }
  }

  .message-warn { background-color: var(--lose-bg); }

  /* ---- 手を選ぶボタン ---- */
  .hand-picker {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: clamp(.5rem, 3vw, 1.25rem);
  }

  .hand-button {
    display: grid;
    justify-items: center;
    gap: .25rem;
    padding: .4rem .25rem;
    font-weight: 700;
    background-color: transparent;
    border: 3px solid transparent;
    border-radius: var(--radius-m);
    cursor: pointer;
    transition: translate .2s var(--ease), background-color .2s, opacity .2s, filter .2s;

    img {
      inline-size: clamp(3.25rem, min(18vw, 9dvh), 7rem);
      block-size: auto;
    }

    &:hover:not(:disabled) {
      translate: 0 -4px;
      background-color: color-mix(in srgb, var(--skin) 40%, var(--surface));
    }

    &:active:not(:disabled) { translate: 0 0; }

    /* 開始前・結果表示中は押せないことを、色を抜いて伝える */
    &:disabled {
      cursor: default;
      opacity: .45;
      filter: grayscale(.8);
    }

    /* さっき出した手は、色を戻して枠で示す */
    &.is-chosen {
      opacity: 1;
      filter: none;
      border-color: var(--line);
      background-color: color-mix(in srgb, var(--skin) 40%, var(--surface));
    }
  }

  .start-button {
    justify-self: center;
    min-inline-size: min(100%, 16rem);
    min-block-size: 3rem;
    font-size: 1.05rem;
  }

  /* 開始前は再生、2 回目以降はやり直しのアイコンを出す */
  .game[data-state="idle"] .icon-again,
  .game:not([data-state="idle"]) .icon-start { display: none; }

  /* ---- 対戦成績 ---- */
  /* 縦に並べ、残った高さを履歴の欄に割り当てる */
  .record {
    display: flex;
    flex-direction: column;
    gap: .75rem;
    padding: clamp(1.25rem, 5vw, 2rem);
    background-color: var(--surface);
    border-radius: var(--radius-m);
    box-shadow: var(--shadow-m);
    /* この要素の幅で中身を切り替えられるようにする（コンテナクエリ）。
       成績は広い画面では右の列、狭い画面ではパネルになり、画面幅と自分の幅が一致しないため */
    container: record / inline-size;

    /* 狭い画面では、画面の下からせり上がるパネルにする */
    @media (width < 60rem) {
      position: fixed;
      inset-inline: 0;
      inset-block-end: 0;
      z-index: 30;
      max-block-size: 90dvh;
      overflow-y: auto;
      overscroll-behavior: contain;
      border-end-start-radius: 0;
      border-end-end-radius: 0;
      /* 閉じているときは画面の外に置き、読み上げやキーボード操作の対象からも外す */
      translate: 0 100%;
      visibility: hidden;
      /* 閉じるときは、下がりきる .3s 後に visibility を切り替え、動きを最後まで見せる */
      transition: translate .3s var(--ease), visibility 0s .3s, box-shadow .3s;

      &.is-open {
        translate: 0 0;
        visibility: visible;
        /* 大きく広げた影で、後ろの画面を暗くする。
           vmax は画面の縦横の長いほうの 1% なので、100vmax 広げればどの画面でも全体を覆える */
        box-shadow: 0 0 0 100vmax rgb(31 28 28 / .5);
        transition: translate .3s var(--ease), box-shadow .3s;
      }
    }
  }

  /* パネルを開いている間は、後ろの画面をスクロールさせない。
     :has() は「中に〜を含む」要素を選ぶので、開いたパネルを含む body に効く */
  body:has(.record.is-open) { overflow: hidden; }

  .record-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
  }

  .record-title { font-size: 1.3rem; }

  .record-close {
    inline-size: 2.75rem;
    block-size: 2.75rem;
    box-shadow: none;

    @media (width >= 60rem) { display: none; }
  }

  .record-heading {
    margin-block-start: .25rem;
    font-size: 1rem;
    color: var(--muted);
  }

  /* 狭い画面のパネルでは、パネル全体をスクロールする。
     長くなる履歴は最後に回し、ボタン類が先に見えるようにする */
  @media (width < 60rem) {
    .history-part { order: 1; }
  }

  .record-summary {
    font-weight: 700;
    text-align: center;
  }

  .record-note {
    font-size: .85rem;
    color: var(--muted);
    text-wrap: pretty;
  }

  .stats {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: .6rem;

    /* 成績パネル（record）の幅が 19rem 以上あれば、4 つを 1 列に並べる */
    @container record (width >= 19rem) {
      grid-template-columns: repeat(4, minmax(0, 1fr));
    }
  }

  .stat {
    display: grid;
    justify-items: center;
    padding: .6rem .25rem .5rem;
    background-color: color-mix(in srgb, var(--ink) 4%, var(--surface));
    border-block-start: 5px solid var(--line);
    border-radius: var(--radius-s);

    &[data-result="win"]  { border-block-start-color: var(--yellow); }
    &[data-result="lose"] { border-block-start-color: var(--red); }
    &[data-result="draw"] { border-block-start-color: var(--blue); }

    dt { font-size: .8rem; color: var(--muted); }

    dd {
      /* 成績パネルの幅に合わせて縮め、「100%」も 1 行に収める。cqi はコンテナの幅の 1% */
      font-size: clamp(1.2rem, 6.5cqi, 1.6rem);
      font-weight: 700;
      line-height: 1.3;
      font-variant-numeric: tabular-nums;
    }
  }

  /* ---- 履歴 ----
     カードに残った高さを埋め、収まらない分は欄の中でスクロールする（最大 100 件）。
     高さが足りなくても、3 件分は必ず見えるようにする */
  .history,
  .history-empty {
    --row: 2.6rem;  /* 1 件分の高さ（行の間隔を含む。実測 41.6px） */
    /* flex: 1 1 0 は「中身の量に関係なく、残った高さを使う」という指定。
       中身の量から始める auto にすると、100 件分の高さまでカードが伸びてしまう */
    flex: 1 1 0;
    min-block-size: calc(var(--row) * 3);
  }

  .history {
    display: grid;
    align-content: start;
    gap: .35rem;
    overflow-y: auto;
    /* 欄の端までスクロールしても、ページ全体はつられてスクロールしない */
    overscroll-behavior: contain;
    padding-inline-end: .25rem;

    /* 狭い画面のパネルでは欄の中をスクロールさせず、件数どおりに並べる */
    @media (width < 60rem) {
      flex: none;
      overflow: visible;
    }

    &[hidden] { display: none; }
  }

  .history-count {
    font-size: .85rem;
    font-weight: 400;
  }

  .history-item {
    display: grid;
    grid-template-columns: auto 1fr auto;
    align-items: center;
    gap: .75rem;
    padding: .4rem .5rem .4rem .75rem;
    font-size: .9rem;
    border-radius: var(--radius-s);

    /* 1 行おきに背景を付け、横に長い行を目で追いやすくする */
    &:nth-child(odd) { background-color: color-mix(in srgb, var(--ink) 4%, var(--surface)); }
  }

  .history-time {
    font-size: .8rem;
    color: var(--muted);
    font-variant-numeric: tabular-nums;
  }

  .history-badge {
    padding: .1rem .7rem;
    font-size: .8rem;
    font-weight: 700;
    border-radius: 999px;

    [data-result="win"] &  { background-color: var(--win-bg); }
    [data-result="lose"] & { background-color: var(--lose-bg); }
    [data-result="draw"] & { background-color: var(--draw-bg); }
  }

  .history-empty {
    font-size: .9rem;
    color: var(--muted);

    &[hidden] { display: none; }
  }

  /* ---- 成績データの操作 ---- */
  /* 3 つのボタンを 1 行に並べる */
  .data-actions {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: .5rem;

    .button {
      gap: .35rem;
      padding-inline: .5rem;
      white-space: nowrap;
    }
  }

  .data-message {
    min-block-size: 1.6em;
    font-size: .9rem;

    &[data-tone="success"] { color: var(--text); }
    &[data-tone="warn"],
    &[data-tone="error"] { color: var(--danger); font-weight: 700; }
  }
}

/* ============================================
   utilities — 読み上げ専用・動き・JS 無効時
   ============================================ */
@layer utilities {
  /* 画面には出さず、読み上げには残す。display: none にすると読み上げからも消えてしまう */
  .visually-hidden,
  .skip-link:not(:focus) {
    position: absolute;
    inline-size: 1px;
    block-size: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }

  .skip-link:focus {
    position: fixed;
    inset-block-start: .75rem;
    inset-inline-start: .75rem;
    z-index: 20;
    padding: .5rem 1rem;
    background-color: var(--surface);
    border-radius: var(--radius-s);
    box-shadow: var(--shadow-m);
  }

  /* アイコンの <symbol> をまとめた SVG。<use> から参照するだけなので、場所を取らないようにする */
  .icon-sprite {
    position: absolute;
    inline-size: 0;
    block-size: 0;
    overflow: hidden;
  }

  /* JavaScript が動かないときは、押しても何も起きない部品を隠す */
  .no-js :is([data-ui="message"], .hand-picker, .start-button, .data-actions, .header-actions, .record-close) {
    display: none;
  }

  /* JavaScript が動かないとパネルを開けないので、成績はページの流れの中に置く */
  .no-js .record {
    position: static;
    translate: none;
    visibility: visible;
  }

  @keyframes shake {
    0%, 100% { rotate: 0deg; translate: 0 0; }
    25%      { rotate: -8deg; translate: -4px 0; }
    75%      { rotate: 8deg; translate: 4px 0; }
  }

  @keyframes pop {
    0%   { scale: .9; }
    60%  { scale: 1.06; }
    100% { scale: 1; }
  }

  /* OS で「視差効果を減らす」などを選んでいる人には、動きをほぼなくす。
     utilities は最後の層なので、詳細度の低い * でも、各部品の指定にそれだけで勝つ。 */
  @media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
      animation-duration: .01ms;
      animation-iteration-count: 1;
      transition-duration: .01ms;
    }
  }
}
