@layer components {
  /*
    その場で書き換えられる値。Highriseの右の列の「Background info　Edit」（structure.md）のように、項目名は小さな太字、値は下線も枠もない文字にする。
    値の行は表示でも編集でも同じ箱（文字の幅のまま、高さは欄と同じ）にし、面だけを文字の外へ張り出して描く。文字の書き始めと上下の位置は動かさない。
    表示の箱は値と控えめな鉛筆だけを包み、ホバーすると37signalsの黄色のハイライト（#ffffcc）を出す（ホバーで出すのは推測）。値を押しても鉛筆を押しても編集を始める。
    編集中はBC2のTo-doの題名のその場での編集と同じく、枠と面を持たず、文字の下に1pxの点線だけを引く。
    実測: basecamp2-thirdparty/bc2-todolist-inline-edit-youtube-2014.jpg (130, 395, 610, 60)。文字は表示の時と同じ位置のまま、
    下に灰色の点線が欄の幅だけ伸び、その下に「Save changes or Cancel」を置く。点線の色と間隔は controls.md 6b章
    （bc2-tour-2014-01-name-project.jpg、2倍: 1px dotted #cccccc。2画素描いて2画素空ける）。
    フォーカスした欄は、点線を他の欄のフォーカスと同じ青（#7cb0e2）の2pxの実線にする（手本はキャレットだけ。推測）。
    確定・取消は一行でも複数行でも欄の下に並べる。
    確定すると、鉛筆の領域に完了のマークを出す（アニメーションは使わない）。
  */
  .rx-editable-property {
    /* 入力欄のフォーカスの輪の色（--rx-focus-glow と同じ #7cb0e2 の55%）。 */
    --rx-editable-glow: color-mix(in srgb, var(--rx-focus-border) 55%, transparent);
    /* 値の行の高さは欄とButtonの高さ。行の文字は上下の余りを半分ずつ空けて置く。 */
    --rx-editable-row: var(--rx-button-size);
    --rx-editable-pad: calc((var(--rx-editable-row) - 10em / 7) / 2);
    /* 面を文字の外へ張り出す幅は、鉛筆の領域の中でアイコンが端から空く幅と同じにし、面の端・値・鉛筆の間をそろえる。 */
    --rx-editable-inset: calc((var(--rx-editable-row) - 1em) / 2);
    --rx-editable-start: calc(-1 * var(--rx-editable-inset));
    display: grid;
    /* 並べた隣の欄が高くても、名前と値の行を伸ばさない。 */
    align-content: start;
    gap: var(--rx-space-1);
    min-inline-size: 0;
    font-size: var(--rx-label);
    line-height: var(--rx-label-leading);
    &:dir(rtl) {
      --rx-editable-start: var(--rx-editable-inset);
    }
  }

  .rx-editable-property > .label {
    color: var(--rx-text);
    font-weight: var(--rx-label-weight);
  }

  .rx-editable-property > .preview[hidden],
  .rx-editable-property > .editor[hidden] {
    display: none;
  }

  /*
    表示の箱は値と鉛筆だけを包み、文字の幅のまま置いて書き始めを名前にそろえ、鉛筆を値から離さない。
    面は箱をずらした影で先頭側にだけ文字の外へ張り出して描く（影は横の大きさに数えないので、狭い場所でも横にはみ出さない。
    鉛筆の領域が末尾側の余白になる）。ホバーすると黄色の面を一枚だけ出し、鉛筆にフォーカスがある時は、他の欄のフォーカスと同じ青い縁と淡い青の輪を出す。
  */
  .rx-editable-property > .preview {
    --rx-editable-face: transparent;
    border-radius: var(--rx-radius-mark);
    background: var(--rx-editable-face);
    display: flex;
    align-items: start;
    inline-size: fit-content;
    min-inline-size: 0;
    max-inline-size: 100%;
    position: relative;
    box-shadow: var(--rx-editable-start) 0 0 0 var(--rx-editable-face);
    /*
      完了のマークは、鉛筆と同じ領域に描く（値の後ろに場所を取らず、鉛筆を値から離さない）。
      確定した時（data-saved="true"）だけ出し、その間は鉛筆を隠す。
    */
    &::after {
      content: "";
      position: absolute;
      inset-block-start: calc((var(--rx-editable-row) - 1em) / 2);
      inset-inline-end: calc((var(--rx-editable-row) - 1em) / 2);
      inline-size: 1em;
      block-size: 1em;
      background: var(--rx-success);
      mask: url("../assets/check.svg") center / contain no-repeat;
      opacity: 0;
      pointer-events: none;
    }
    &:has(> .edit:enabled):hover {
      --rx-editable-face: var(--rx-mark);
    }
    &:has(> .edit:focus-visible) {
      box-shadow:
        var(--rx-editable-start) 0 0 0 var(--rx-editable-face),
        var(--rx-editable-start) 0 0 var(--rx-stroke-width) var(--rx-focus-border),
        0 0 0 var(--rx-stroke-width) var(--rx-focus-border),
        var(--rx-editable-start) 0 0 calc(var(--rx-stroke-width) + 0.1875rem)
          var(--rx-editable-glow),
        0 0 0 calc(var(--rx-stroke-width) + 0.1875rem) var(--rx-editable-glow);
    }
  }

  /* 鉛筆は値のすぐ後ろに置き、どの値を書き換えるのかを離さない。 */
  .rx-editable-property > .preview > .value {
    flex: 0 1 auto;
    min-inline-size: 0;
    padding-block: var(--rx-editable-pad);
    overflow-wrap: anywhere;
    /* 未登録は、まだ何も書いていない状態として控えめな色にする。 */
    &[data-empty="true"] {
      color: var(--rx-muted);
    }
  }

  /* 値そのものを押しても編集を始める。 */
  .rx-editable-property > .preview:has(> .edit:enabled) > .value {
    cursor: text;
  }

  /* 鉛筆は自分の面とリングを持たず、箱の面とリングで示す。普段は灰色で控えめに置き、ホバーした時だけリンクの色にする。 */
  .rx-editable-property > .preview > .edit.rx-button {
    flex: none;
    color: var(--rx-muted);
    &:hover:not(:disabled) {
      color: var(--rx-link-hover);
    }
    &:is(:hover, :active) {
      background: transparent;
    }
    &:focus-visible {
      outline: 0;
    }
  }

  .rx-editable-property > .editor {
    display: grid;
    justify-items: start;
    gap: var(--rx-space-2);
    min-inline-size: 0;
  }

  /*
    編集中の欄は、列の幅いっぱい（30remまで）に広げる。文字は箱の端から書く（表示と同じ位置）。
    枠・面・角丸を持たず、下端に1px #ccc の点線（1px描いて1px空ける）を引く。点線は背景の繰り返しで描き、欄の高さを変えない。
  */
  .rx-editable-property > .editor > .rx-input {
    --rx-input-size: var(--rx-editable-row);
    --rx-input-border-size: 0rem;
    --rx-editable-dots: #cccccc;
    --rx-editable-underline: linear-gradient(to right, var(--rx-editable-dots) 50%, transparent 50%)
      left bottom / calc(2 * var(--rx-stroke-width)) var(--rx-stroke-width) repeat-x;
    inline-size: 100%;
    /* 一行の入力欄の文字（12px）ではなく表示の値と同じ大きさで書き、編集を始めても文字の大きさと位置を変えない。 */
    font-size: var(--rx-label);
    max-inline-size: 30rem;
    padding-inline: 0;
    border-radius: 0;
    background: var(--rx-editable-underline);
    box-shadow: none;
    &:focus-visible {
      background: linear-gradient(var(--rx-focus-border), var(--rx-focus-border)) left bottom / 100%
        0.125rem no-repeat;
      box-shadow: none;
    }
    &[data-invalid="true"],
    &:user-invalid {
      --rx-editable-dots: var(--rx-danger);
      &:focus-visible {
        background: linear-gradient(var(--rx-danger), var(--rx-danger)) left bottom / 100% 0.125rem
          no-repeat;
      }
    }
  }

  /*
    一行の欄は、共通Inputのように行高を内寸いっぱいにせず、複数行と同じく文字の行高と上下の余白で置く。
    枠のない面では、内寸いっぱいの行高だと選択の色が面の上下の端まで塗られるため。
  */
  .rx-editable-property > .editor > input.rx-input {
    padding-block: calc((var(--rx-input-size) - 10em / 7) / 2);
    line-height: calc(10 / 7);
  }

  .rx-editable-property > .editor > .actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--rx-space-1);
  }

  /* 複数行は改行をそのまま表示し、編集中は3行分から内容に合わせて伸ばす。 */
  .rx-editable-property[data-multiline="true"] {
    & > .preview > .value {
      white-space: pre-wrap;
    }
    & > .editor > .rx-input {
      min-block-size: calc(3 * 10em / 7 + 2 * var(--rx-editable-pad));
      field-sizing: content;
      resize: none;
    }
  }

  .rx-editable-property:not([data-state]) > .editor > .actions {
    display: none;
  }
  /* タッチ端末では、鉛筆がButtonの大きさになるので、値の行と欄も同じ高さにする。 */
  @media (pointer: coarse) {
    .rx-editable-property {
      --rx-editable-row: 2.75rem;
    }
    /* タッチ端末の欄は拡大を防ぐため16pxで書くので、表示の値も同じ大きさにし、編集を始めても文字の大きさを変えない。 */
    .rx-editable-property > .preview > .value,
    .rx-editable-property > .editor > .rx-input {
      font-size: max(1rem, var(--rx-label));
    }
  }
  .rx-editable-property[data-saved="true"] > .preview::after {
    opacity: 1;
  }
  .rx-editable-property[data-saved="true"] > .preview > .edit > .rx-icon {
    opacity: 0;
  }
  @media (forced-colors: active) {
    /* 背景の点線は消えるので、欄と鉛筆のフォーカスは張り出す幅の輪郭で示す。 */
    .rx-editable-property > .editor > .rx-input {
      outline: var(--rx-stroke-width) solid CanvasText;
      outline-offset: var(--rx-editable-inset);
      &:focus-visible {
        outline: 0.125rem solid Highlight;
      }
    }
    .rx-editable-property > .preview::after {
      background: CanvasText;
    }
    /* 影は消えるので、鉛筆のフォーカスは箱の輪郭で示す。 */
    .rx-editable-property > .preview:has(> .edit:focus-visible) {
      outline: 0.125rem solid Highlight;
      outline-offset: var(--rx-editable-inset);
    }
  }
}
