/* Suisou — Surface（面）

     <div data-suisou-surface="panel">面 + 罫。いちばん普通の容れ物</div>
     <div data-suisou-surface="item">1段手前。入力欄や入れ子の容れ物</div>
     <div data-suisou-surface="panel bare">罫なし</div>
     <div data-suisou-surface="none">面を持たない。罫だけで囲う</div>

   ★値は「段」が必須で1つ、「装飾」が任意。
       段    panel / item / overlay / none   どの面に載るか
       装飾  bare / tight / bleed             罫と余白
     段を書かずに装飾だけ書いても意味が通らない（面だと宣言しておいて
     どの段か言っていない）。tools/lint_css.py が検査する。

   ★面は「閉じた集合」なので値で選ぶ。部品（media / btn / avatar …）は
     これから増えるので属性そのものが名前になる。形が違えば層が違うと分かる。

       data-suisou-surface="panel"   面 … 値で選ぶ
       data-suisou-media             部品 … 属性が名前

   値は面の階段（bg < panel < item < overlay）とそのまま対応する。
   surface="item" は --suisou-item を使う。覚えることが減る。

   ★影は持たない。「線形デザインだから」ではなく、ダーク専用では影が機能しないため。
     影は下地を暗くする技法だが、Suisou の下地は既に暗いので暗くする余地が無い。
     実測（hadal）: 一番濃い scrim を一番明るい面に落として輝度比 1.45 ――
     Suisou 自身の一番緩い可視性の基準（装飾罫の 1.5）にすら届かない。
     Tailwind の shadow-xl（黒 α0.10）に至っては 1.02 で、何も起きていない。

   ★暗い側で効くのは光の方（白 α0.15 を panel に落とすと 3.45）。ただし
     line-strong を罫に回すと 3.10 で、ほぼ同じ強さになる。つまり
     **Suisou の罫は、ぼかしていない白い光**。白いグロウを足すと同じものが
     二重になって輪郭が濁るので、足さない。Linear などが内側に白い光を入れるのは
     罫が極端に薄いからで、罫を 3:1 で引く Suisou には代用品が要らない。

   中身の並べ方は持たない。並びは部品（media）とユーティリティの担当なので、
   同じ要素に同居できる:  <div data-suisou-surface="panel" data-suisou-media> */

[data-suisou-surface] {
  box-sizing: border-box;
  border: 1px solid var(--suisou-line-weak);
  border-radius: var(--suisou-radius);
  padding: var(--suisou-space-3);
}

/* 段 … どの面に載るか。必ず1つ書く

   ★段を上げたら装飾罫も差し替える（2026-08-22）。

     罫は2本とも「いま載っている面の上で決まった比になる線」で、面ごとに
     値が違う（solve.py の resolve_line）。装飾罫は 1.51:1、機能の線
     （入力枠・連結の器・面の縁）は 3.10:1。段を上げた要素が
     自分の中の既定を書き換えるので、**中に入る部品は何も知らなくていい**
     ―― Tag も Row も Code も表も、var(--suisou-line-weak) と書くだけで
     載っている面に合った濃さになる。CSS 変数が継承する性質をそのまま使う。

     以前は L44 の1つだけを全部の面に引いていたので、面が暗いほど罫が
     強く出ていた（overlay 1.51:1 に対し bg では 2.53:1 と1.67倍）。
     PAIRS は下限しか見ないため、強すぎる側は誰も検査していなかった。

   ★none は段を上げないので差し替えない。まわりの面の値をそのまま継ぐ。 */
[data-suisou-surface~="panel"] {
  background: var(--suisou-panel);
  --suisou-line-weak: var(--suisou-line-weak-panel);
  --suisou-line-strong: var(--suisou-line-strong-panel);
}
[data-suisou-surface~="item"] {
  background: var(--suisou-item);
  --suisou-line-weak: var(--suisou-line-weak-item);
  --suisou-line-strong: var(--suisou-line-strong-item);
}
[data-suisou-surface~="none"]  { background: transparent; }   /* 段を上げず、罫だけで囲う */


/* 浮くもの。モーダル・ポップオーバー・ドロップダウン。
   ★他の面と違い「下地が読めない」のが唯一の特徴なので、明度差だけに頼らず
     罫を強くする。line-strong on overlay は PAIRS で 3.0 以上を検証済み。
   後ろが操作できないことは面ではなく scrim（<dialog> の ::backdrop）が伝える。 */
[data-suisou-surface~="overlay"] {
  background: var(--suisou-overlay);
  border-color: var(--suisou-line-strong-overlay);
  --suisou-line-weak: var(--suisou-line-weak-overlay);
  --suisou-line-strong: var(--suisou-line-strong-overlay);
}

/* 後ろを塞ぐ膜。<dialog> にも popover にも同じ疑似要素があるので1行で足りる。
   ★開閉に JS が要らない（掟4）―― popovertarget 属性か <dialog> の
     formmethod="dialog" で完結する。 */
[data-suisou-surface~="overlay"]::backdrop { background: var(--suisou-scrim); }

/* 出入りをふわっとさせる。★[popover] / <dialog> のときだけに絞ってある ――
   overlay の面を静的な箱として使うこともあるので、無条件に opacity: 0 を
   置くと消えてしまう。

   display と overlay を allow-discrete で繋ぎ、@starting-style で
   「開く直前の姿」を与えるのが、JS なしで出入りを animate する定石。
   未対応のブラウザでは単に animate しないだけで、壊れない。 */
:where([popover], dialog)[data-suisou-surface~="overlay"] {
  opacity: 0;
  transition: opacity var(--suisou-motion) var(--suisou-ease),
              display var(--suisou-motion) allow-discrete,
              overlay var(--suisou-motion) allow-discrete;
}
:where([popover], dialog)[data-suisou-surface~="overlay"]:where(:popover-open, [open]) {
  opacity: 1;
}
@starting-style {
  :where([popover], dialog)[data-suisou-surface~="overlay"]:where(:popover-open, [open]) {
    opacity: 0;
  }
}

/* 膜も一緒に。中身より少し速く消えると、閉じたことが先に伝わる */
:where([popover], dialog)[data-suisou-surface~="overlay"]::backdrop {
  opacity: 0;
  transition: opacity var(--suisou-motion-fast) var(--suisou-ease),
              display var(--suisou-motion-fast) allow-discrete,
              overlay var(--suisou-motion-fast) allow-discrete;
}
:where([popover], dialog)[data-suisou-surface~="overlay"]:where(:popover-open, [open])::backdrop {
  opacity: 1;
}
@starting-style {
  :where([popover], dialog)[data-suisou-surface~="overlay"]:where(:popover-open, [open])::backdrop {
    opacity: 0;
  }
}

/* 端に寄せて浮く形。ハンバーガーの中身・モバイルのメニュー。overlay と組で書く:

     <button data-suisou-button="icon" popovertarget="menu">…</button>
     <div id="menu" popover data-suisou-surface="overlay drawer">…</div>

   ★popover と組むと開閉に JS が要らない（掟4）―― ESC・外側クリックで閉じるのも
     ::backdrop の膜もブラウザが持つ。出入りはフェードではなく端からの滑り。
   ★幅の既定は 20rem。現場は --suisou-drawer を上書きして変える（実寸は現場のもの）。
     3現場ぶんの前例: wixdex のサイドバー / プレビューのメニュー / pickker のドロワー

   ★どちらの端から出るかは start / end で選ぶ（既定は end ＝ 右）。

       <div popover data-suisou-surface="overlay drawer">…</div>        右から
       <div popover data-suisou-surface="overlay drawer start">…</div>  左から

     論理方向の名前なので、いつか縦書き・RTL を扱うときもそのまま通る。
     左を足したのは Mado の要求（2026-08-22）―― ナビゲーションのドロワーは
     慣習的に左から出る。wixdex は「後から現れる補助」で右だったので気づけなかった。
     **2人目の客が最初に見つけた穴。** 単画面のツールと多画面のダッシュボードでは
     ドロワーの意味が違う（wixdex＝道具箱 / Mado＝行き先の一覧）。 */
[data-suisou-surface~="drawer"] {
  --suisou-drawer: 20rem;
  position: fixed;
  inset: 0 0 0 auto;                 /* 既定は行末（LTR なら右）に貼り付く */
  margin: 0;                         /* popover の UA 既定（中央寄せ）を外す */
  height: 100dvh;
  max-height: none;
  width: min(var(--suisou-drawer), 90vw);
  border: 0;
  border-inline-start: 1px solid var(--suisou-line-strong);
  border-radius: 0;
}

/* 行頭（LTR なら左）から出す */
[data-suisou-surface~="drawer"][data-suisou-surface~="start"] {
  inset: 0 auto 0 0;
  border-inline-start: 0;
  border-inline-end: 1px solid var(--suisou-line-strong);
}

/* 滑りの出入り。overlay のフェードを上書きする（この節が後にある理由）。
   構えは overlay のフェードと同じ: display / overlay を allow-discrete で繋ぎ、
   @starting-style が開く直前の姿を与える。未対応なら滑らず出るだけ。
   ★隠れている位置は端の外。start なら左の外（-100%）へ回る。 */
:where([popover], dialog)[data-suisou-surface~="drawer"] {
  --suisou-drawer-hidden: 100%;
  opacity: 1;
  translate: var(--suisou-drawer-hidden) 0;
  transition: translate var(--suisou-motion) var(--suisou-ease),
              display var(--suisou-motion) allow-discrete,
              overlay var(--suisou-motion) allow-discrete;
}
:where([popover], dialog)[data-suisou-surface~="drawer"][data-suisou-surface~="start"] {
  --suisou-drawer-hidden: -100%;
}
:where([popover], dialog)[data-suisou-surface~="drawer"]:where(:popover-open, [open]) {
  translate: 0 0;
}
@starting-style {
  :where([popover], dialog)[data-suisou-surface~="drawer"]:where(:popover-open, [open]) {
    translate: var(--suisou-drawer-hidden) 0;
  }
}

/* 装飾 … 任意 */
[data-suisou-surface~="bare"] { border-color: transparent; }  /* 罫を消す */

/* 余白の段。★横は動かさない ―― 面を縦に並べたとき、中身の左端が揃っていないと
   階段がガタつく。詰めたいのはたいてい縦（ヘッダ行・入力行）だった。
   実際、作例で手書きされていた4つのうち3つが「縦だけ詰めたい」で、
   残る1つは「端まで届かせたい」だった。段はこの2つで足りる。 */
[data-suisou-surface~="tight"] { padding-block: var(--suisou-space-2); }

/* まだ何も無い場所（2026-08-22、Mado の4現場から昇格）。

     <div data-suisou-surface="panel empty" data-suisou-layout="stack center">
       <p>まだ質問がありません</p>
     </div>

   罫を破線にして「ここに入るはずのものが無い」を示す。実線は「在る物の輪郭」で、
   空の入れ物に実線を引くと中身が在るように見える ―― 破線はその区別のための線。

   ★色は line-strong。装飾罫より強くするのは、空表示が**面の中で一番目立つべき
     もの**だから（他に何も無いので、これが唯一の手がかりになる）。
   ★Mado の4現場: プロフィールの箱一覧 ×2 / 通知設定 / 受信トレイ。
     どれも「0件のとき」で、4つとも border-dashed + border-border-strong を
     手書きしていた。 */
[data-suisou-surface~="empty"] {
  border-style: dashed;
  border-color: var(--suisou-line-strong);
}

/* 中身を端まで届かせる。行が自分で余白を持つ一覧など。
   罫と角丸は残るので、中身は角丸に沿って切られる（overflow は持たせない） */
[data-suisou-surface~="bleed"] { padding: 0; }
