/* Tenant block home.

   Two levels: sections own layout (background, width, padding, alignment,
   columns); blocks own content and nothing else. Everything a document can
   influence arrives as a class or a custom property -- never as an
   author-supplied CSS string.

   Colour comes from the gallery's theme tokens, never from a preset, so a
   published home follows light/dark with the album pages it sits beside. A
   preset decides type scale and rhythm only. */

:root {
  --home-measure: 62ch;
  /* One value for the inner's inline padding: editing chrome that wants to
     line up with the text has to subtract exactly this much. */
  --home-inner-pad: clamp(1rem, 3vw, 2rem);
  /* Every section's content sits on this one measure, whatever its width
     setting -- `full` bleeds the *background*, never the text. Two different
     text edges on one page is what makes a block home look unaligned. */
  --home-content-max: 72rem;
  --home-narrow-max: 46rem;
}

/* The four steps of the page's vertical rhythm, all read off the preset's own
   --home-gap. They are declared on .home-page rather than :root because that is
   the element the preset class sits on -- var() resolves against the element
   that declares it, and at :root --home-gap does not exist yet. */
.home-page {
  --home-flow: var(--home-gap);
  --home-flow-tight: calc(var(--home-gap) * 0.35);
  --home-flow-loose: calc(var(--home-gap) * 1.5);
  --home-flow-heading: calc(var(--home-gap) * 1.75);
}

/* --- Presets ------------------------------------------------------------ */

.home-page--preset-quiet {
  --home-display-size: clamp(1.9rem, 3.4vw, 2.8rem);
  --home-display-weight: 600;
  --home-display-tracking: -0.015em;
  --home-display-leading: 1.2;
  --home-body-size: 1rem;
  --home-body-leading: 1.8;
  --home-rule: 1px;
  --home-radius: var(--radius-lg);
  --home-pad-compact: 1.5rem;
  --home-pad-default: clamp(2.5rem, 5vw, 4rem);
  --home-pad-tall: clamp(4rem, 9vw, 7rem);
  --home-gap: clamp(1.25rem, 2.5vw, 2rem);
}

.home-page--preset-editorial {
  --home-display-size: clamp(2.4rem, 5.5vw, 4.5rem);
  --home-display-weight: 700;
  --home-display-tracking: -0.035em;
  --home-display-leading: 1.02;
  --home-body-size: 1.0625rem;
  --home-body-leading: 1.7;
  --home-rule: 2px;
  --home-radius: var(--radius-sm);
  --home-pad-compact: 1.75rem;
  --home-pad-default: clamp(3rem, 6vw, 5rem);
  --home-pad-tall: clamp(5rem, 11vw, 9rem);
  --home-gap: clamp(1.5rem, 3vw, 2.5rem);
}

.home-page--preset-poster {
  --home-display-size: clamp(2.2rem, 6.5vw, 5.5rem);
  --home-display-weight: 800;
  --home-display-tracking: 0.01em;
  --home-display-leading: 0.95;
  --home-body-size: 0.9375rem;
  --home-body-leading: 1.65;
  --home-rule: 3px;
  --home-radius: 0px;
  --home-pad-compact: 1.25rem;
  --home-pad-default: clamp(2rem, 4.5vw, 3.5rem);
  --home-pad-tall: clamp(4.5rem, 10vw, 8rem);
  --home-gap: clamp(0.75rem, 1.5vw, 1.25rem);
}

.home-page--preset-poster .home-header {
  text-transform: uppercase;
}

/* --- Page --------------------------------------------------------------- */

/* Block layout, not flex: a plain section spends its vertical space as a
   margin so two stacked sections collapse to one gap instead of summing
   their paddings. Flex column would suppress that collapse. */
.home-page {
  color: var(--fg);
  display: block;
  padding-bottom: 4rem;
  width: 100%;
}

/* --- Section ------------------------------------------------------------ */

.home-section {
  background-position: center;
  background-size: cover;
  position: relative;
  width: 100%;
}

/* Full-bleed is relative to the container, not the viewport: this pane is
   inset by the gallery sidebar, so 50vw math would drag the section out from
   under the content column and force a horizontal scrollbar.

   `full` bleeds the background across the pane; every other width paints its
   background on the inner box instead, so it reads as a panel. The text
   measure is the same in all three cases -- only `narrow` pulls in. */
.home-section--w-full {
  background-color: var(--home-section-bg, transparent);
  background-image: var(--home-section-image, none);
}
.home-section:not(.home-section--w-full) > .home-section__inner {
  background-color: var(--home-section-bg, transparent);
  background-image: var(--home-section-image, none);
  background-position: center;
  background-size: cover;
  border-radius: var(--home-radius);
}
.home-section--w-narrow > .home-section__inner { max-width: var(--home-narrow-max); }

.home-section__inner {
  isolation: isolate;
  margin-inline: auto;
  max-width: var(--home-content-max);
  padding-inline: var(--home-inner-pad);
  position: relative;
  /* Above the section's own scrim, which is a later sibling in paint order. */
  z-index: 1;
  width: 100%;
}

.home-section--pad-none { --home-section-pad: 0rem; }
.home-section--pad-compact { --home-section-pad: var(--home-pad-compact); }
.home-section--pad-default { --home-section-pad: var(--home-pad-default); }
.home-section--pad-tall { --home-section-pad: var(--home-pad-tall); }

/* A section that paints something needs padding -- the background has to
   extend past the text. A section that paints nothing uses margin, which
   collapses with its neighbour's. */
.home-section > .home-section__inner { padding-block: var(--home-section-pad, 0rem); }
.home-section--plain > .home-section__inner {
  margin-block: var(--home-section-pad, 0rem);
  padding-block: 0;
}

.home-section--align-center { text-align: center; }
.home-section--align-center .home-paragraph { margin-inline: auto; }
.home-section--align-center .home-sns,
.home-section--align-center .home-col { align-items: center; }

/* A photograph is not a theme surface: pin the text to the light end and lay a
   scrim under it so any exposure stays legible. Give it a real minimum height
   too -- a photo section whose only block is one heading would otherwise
   render as a letterboxed strip, and the picture is the point. */
.home-section--photo { color: #f4f4f2; }
.home-section--photo > .home-section__inner {
  align-content: end;
  display: grid;
  min-height: var(--home-photo-min, clamp(16rem, 34vw, 26rem));
}
/* The scrim goes wherever the photograph went: on the section when it bleeds,
   on the inner panel when it does not. */
.home-section--photo::after,
.home-section--photo > .home-section__inner::after {
  background: linear-gradient(
    to top,
    rgba(0, 0, 0, 0.72) 0%,
    rgba(0, 0, 0, 0.34) 45%,
    rgba(0, 0, 0, 0.1) 100%
  );
  border-radius: inherit;
  content: "";
  inset: 0;
  pointer-events: none;
  position: absolute;
}
.home-section--photo.home-section--w-full > .home-section__inner::after { content: none; }
.home-section--photo:not(.home-section--w-full)::after { content: none; }
.home-section--photo > .home-section__inner > * { position: relative; z-index: 1; }
.home-section--photo .home-paragraph { color: inherit; }

/* --- Columns ------------------------------------------------------------ */

.home-cols {
  display: grid;
  gap: var(--home-gap);
}

.home-col {
  display: flex;
  flex-direction: column;
  /* Not `gap`. A single gap spaces every pair the same, which reads as a list
     of unrelated things: two sentences of one paragraph stood as far apart as a
     photograph from the heading above it. Rhythm is a property of the pair, so
     it comes from margins -- see "Vertical rhythm" below. */
  min-width: 0;
  position: relative;
}

/* --- Vertical rhythm -----------------------------------------------------

   Four steps, all derived from the preset's --home-gap so a preset still tunes
   the whole page with one number. The order of the rules below IS the
   precedence -- every selector here is one class, so the last match wins:

       default -> tight -> media -> heading

   The editor repeats this table against Editor.js's own DOM (see "Editor.js
   overrides"). The two must not drift: the editor is a preview or it is
   nothing. */

.home-col > * { margin-block-start: var(--home-flow); }

/* Two paragraphs in a row are one thought continuing. A block right after a
   heading belongs to it. */
.home-block--paragraph + .home-block--paragraph,
.home-block--header + * {
  margin-block-start: var(--home-flow-tight);
}

/* A list belongs to the sentence that introduced it. */
.home-block--paragraph + .home-block--list,
.home-block--list + .home-block--paragraph,
.home-block--list + .home-block--list {
  margin-block-start: var(--home-flow-tight);
}

/* A picture, a rule or a pulled quote is a break in the reading, and only
   reads as one with room on both sides. */
.home-block--image,
.home-block--mediaGrid,
.home-block--linkCard,
.home-block--albumLink,
.home-block--compare,
.home-block--quote,
.home-block--delimiter {
  margin-block-start: var(--home-flow-loose);
}

/* A heading opens something. */
.home-block--header { margin-block-start: var(--home-flow-heading); }

/* The spacer IS the spacing. Anything on top of it doubles it. */
.home-block--spacer,
.home-block--spacer + * {
  margin-block-start: 0;
}

/* Nothing above the first block. Two classes, so this outranks the table
   whatever the order. */
.home-col > :first-child { margin-block-start: 0; }

/* A rule down the gutter, so a split column reads as a split and not as text
   that happens to stop early. It is drawn on the pseudo-element rather than as
   a border because a border sits on the column's own edge, off-centre in the
   gap; this one is centred in the gutter. Inset top and bottom so it reads as
   a separator and not as a frame, and faint enough to stay behind the content
   in every preset. */
.home-col + .home-col::before {
  background: color-mix(in srgb, currentColor 14%, transparent);
  bottom: 0.35rem;
  content: "";
  left: calc(var(--home-gap) / -2);
  pointer-events: none;
  position: absolute;
  top: 0.35rem;
  width: 1px;
}

/* One column below the breakpoint: the rule would land above the content, not
   beside it. */
@media (max-width: 768px) {
  .home-col + .home-col::before { content: none; }
}

/* --- Blocks ------------------------------------------------------------- */

.home-block { min-width: 0; }

.home-header {
  font-family: var(--font-display);
  font-size: var(--home-display-size);
  font-weight: var(--home-display-weight);
  letter-spacing: var(--home-display-tracking);
  line-height: var(--home-display-leading);
  margin: 0;
  text-wrap: balance;
}
h2.home-header { font-size: calc(var(--home-display-size) * 0.68); }
h3.home-header { font-size: calc(var(--home-display-size) * 0.48); }

.home-paragraph {
  color: color-mix(in srgb, var(--fg) 88%, transparent);
  font-size: var(--home-body-size);
  line-height: var(--home-body-leading);
  margin: 0;
  max-width: var(--home-measure);
}

/* Pressing Enter on an empty line is how every block editor makes breathing
   room, and the editor duly shows a blank line -- but an empty <p> has no line
   box of its own, so the published page collapsed it to nothing and the spacing
   the owner just made disappeared on publish. The empty inline gives it back
   exactly one line, which is what the editor showed. */
.home-paragraph:empty::before {
  content: "";
  display: inline-block;
}

/* --- Before / after ------------------------------------------------------

   Two frames of the same thing, one clipped over the other, with the position
   carried on a custom property so the only script involved is one line that
   copies the range's value onto it. Without JavaScript the block still shows
   the "after" frame at full size and the range still reads as a control. */

.home-compare {
  aspect-ratio: var(--home-compare-ratio, 3 / 2);
  border-radius: var(--home-radius);
  overflow: hidden;
  position: relative;
  width: 100%;
}
.home-compare__img {
  display: block;
  height: 100%;
  object-fit: cover;
  width: 100%;
}
/* Clipped rather than narrowed: a narrower box would scale the image inside it
   and the two frames would stop lining up. The layer stays full size and only
   its visible part moves. */
.home-compare__clip {
  clip-path: inset(0 calc(100% - var(--home-compare-pos, 50%)) 0 0);
  inset: 0;
  position: absolute;
}
.home-compare__handle {
  background: color-mix(in srgb, white 85%, transparent);
  bottom: 0;
  left: var(--home-compare-pos, 50%);
  pointer-events: none;
  position: absolute;
  top: 0;
  transform: translateX(-50%);
  width: 2px;
}
.home-compare__handle::after {
  background: color-mix(in srgb, white 85%, transparent);
  border-radius: 999px;
  content: "";
  height: 2.2rem;
  left: 50%;
  position: absolute;
  top: 50%;
  transform: translate(-50%, -50%);
  width: 2.2rem;
}
/* The range is the whole surface: invisible, but it is the real control, so
   it keeps its focus ring and its keyboard behaviour. */
.home-compare__range {
  appearance: none;
  background: transparent;
  cursor: ew-resize;
  height: 100%;
  inset: 0;
  margin: 0;
  position: absolute;
  width: 100%;
}
.home-compare__range::-webkit-slider-thumb {
  appearance: none;
  height: 100%;
  opacity: 0;
  width: 2.4rem;
}
.home-compare__range::-moz-range-thumb { height: 100%; opacity: 0; width: 2.4rem; }
.home-compare__range:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.home-compare__label {
  background: color-mix(in srgb, black 55%, transparent);
  border-radius: 999px;
  bottom: 0.75rem;
  color: #fff;
  font-size: 0.75rem;
  letter-spacing: 0.04em;
  padding: 0.2rem 0.6rem;
  pointer-events: none;
  position: absolute;
  text-transform: uppercase;
}
.home-compare__label--before { left: 0.75rem; }
.home-compare__label--after { right: 0.75rem; }

/* --- Lists --------------------------------------------------------------

   One rule set for all three styles: the marker changes, the structure does
   not. Nested lists inherit the type scale rather than shrinking, because a
   sub-point is not a footnote. */

.home-list {
  color: color-mix(in srgb, var(--fg) 88%, transparent);
  display: flex;
  flex-direction: column;
  font-size: var(--home-body-size);
  gap: var(--home-flow-tight);
  line-height: var(--home-body-leading);
  margin: 0;
  max-width: var(--home-measure);
  padding-inline-start: 1.35em;
}
.home-list .home-list {
  margin-block-start: var(--home-flow-tight);
  padding-inline-start: 1.15em;
}
.home-list li {
  margin: 0;
  /* The text span is a block so a wrapped line lines up under the first one
     rather than under the marker. */
  position: relative;
}
.home-list__text { display: block; }

.home-list--checklist {
  list-style: none;
  padding-inline-start: 0;
}
.home-list--checklist li {
  display: flex;
  align-items: baseline;
  gap: 0.55em;
  flex-wrap: wrap;
}
.home-list--checklist .home-list { flex-basis: 100%; padding-inline-start: 1.5em; }
.home-list--checklist .home-list__text { flex: 1; min-width: 0; }
.home-list__mark {
  border: var(--home-rule) solid color-mix(in srgb, currentColor 45%, transparent);
  border-radius: 4px;
  flex: none;
  height: 0.95em;
  position: relative;
  top: 0.12em;
  width: 0.95em;
}
.home-list__mark--on {
  background: var(--home-accent, var(--accent));
  border-color: var(--home-accent, var(--accent));
}
/* The tick is drawn rather than typed: a checkmark glyph sits differently in
   every font stack, and this one has to sit inside a 0.95em box. */
.home-list__mark--on::after {
  border: solid var(--bg, #fff);
  border-width: 0 2px 2px 0;
  content: "";
  height: 0.45em;
  left: 50%;
  position: absolute;
  top: 45%;
  transform: translate(-50%, -50%) rotate(45deg);
  width: 0.25em;
}
.home-list__done > .home-list__text {
  color: var(--muted);
  text-decoration: line-through;
}

.home-paragraph a,
.home-header a,
.home-quote a {
  color: var(--home-accent, var(--accent));
  text-underline-offset: 0.2em;
}

.home-quote {
  border-left: var(--home-rule) solid var(--home-accent, var(--accent));
  margin: 0;
  padding-left: 1.25rem;
}
.home-quote p {
  font-size: calc(var(--home-body-size) * 1.25);
  line-height: 1.55;
  margin: 0;
}
.home-quote cite {
  color: var(--muted);
  display: block;
  font-size: 0.8125rem;
  font-style: normal;
  letter-spacing: 0.06em;
  margin-top: 0.75rem;
  text-transform: uppercase;
}

.home-delimiter {
  background: currentColor;
  border: 0;
  height: var(--home-rule);
  margin: 0;
  opacity: 0.25;
}

.home-spacer--sm { height: 1.5rem; }
.home-spacer--md { height: 3rem; }
.home-spacer--lg { height: 6rem; }

.home-image { margin: 0; }
/* max-width, never width: forcing 100% upscales a small asset into a blurry
   slab. An image shows at its own size, capped by its column. */
.home-image img {
  border-radius: var(--home-radius);
  display: block;
  height: auto;
  max-width: 100%;
}
.home-section--align-center .home-image img { margin-inline: auto; }
.home-image figcaption {
  color: var(--muted);
  font-size: 0.8125rem;
  margin-top: 0.6rem;
}
.home-image a { display: inline-block; }
.home-image a:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 3px; }

.home-button,
.home-album-link {
  align-items: center;
  align-self: flex-start;
  background: var(--home-accent, var(--accent));
  border: 1px solid transparent;
  border-radius: 999px;
  color: var(--on-accent);
  display: inline-flex;
  font-weight: 500;
  gap: 0.5rem;
  padding: 0.6rem 1.4rem;
  text-decoration: none;
  transition: background 0.18s var(--ease-out), transform 0.18s var(--ease-out);
}
.home-section--align-center .home-button,
.home-section--align-center .home-album-link { align-self: center; }
.home-button:hover,
.home-album-link:hover { background: var(--accent-hover); transform: translateY(-1px); }
.home-button:focus-visible,
.home-album-link:focus-visible,
.home-sns__link:focus-visible,
.home-card:focus-visible,
.home-grid__cell:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 3px;
}

.home-badge {
  background: var(--surface-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--muted);
  font-size: 0.6875rem;
  margin-left: 0.5rem;
  padding: 0.1rem 0.4rem;
}

/* Buttons standing next to each other in the document share a row. One word
   per line down a whole column is a list, not a set of choices. */
.home-block-row {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
}
.home-block-row > .home-block { width: auto; }

/* Same in the editor, where each button is still its own Editor.js block: a
   block whose only content is a button shrinks to fit and sits beside the next
   one, so the two surfaces agree on where the buttons are. */
.home-editor__holder .ce-block:has(.home-block--button) {
  display: inline-block;
  vertical-align: top;
  width: auto;
}
/* Only the horizontal gap. Zeroing the top margin here would misalign the two
   inline-blocks by exactly one row gap: the first button carries the spacing
   from whatever it follows, and both sit on the same line. */
.home-editor__holder
  .ce-block:has(.home-block--button)
  + .ce-block:has(.home-block--button) {
  margin-inline-start: 0.6rem;
}

.home-sns { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.home-sns__link {
  border: 1px solid var(--border);
  border-radius: 999px;
  color: inherit;
  font-size: 0.875rem;
  padding: 0.35rem 0.9rem;
  text-decoration: none;
  transition: border-color 0.18s var(--ease-out), color 0.18s var(--ease-out);
}
.home-sns__link:hover {
  border-color: var(--home-accent, var(--accent));
  color: var(--home-accent, var(--accent));
}

.home-album-card {
  background: var(--surface-raised);
  border: 1px solid var(--border);
  border-radius: var(--home-radius);
  color: inherit;
  display: flex;
  flex-direction: column;
  max-width: 18rem;
  overflow: hidden;
  text-decoration: none;
  transition: border-color 0.18s var(--ease-out), transform 0.18s var(--ease-out);
}
.home-album-card:hover {
  border-color: var(--home-accent, var(--accent));
  transform: translateY(-2px);
}
.home-album-card:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 3px;
}
.home-album-card__cover {
  aspect-ratio: 4 / 3;
  display: block;
  object-fit: cover;
  width: 100%;
}
.home-album-card__cover--empty {
  background: linear-gradient(135deg, var(--surface) 0%, var(--border) 100%);
}
.home-album-card__body {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  padding: 0.85rem 1rem 1rem;
}
.home-album-card__title {
  font-weight: 600;
  line-height: 1.35;
}
.home-album-card__count {
  color: var(--muted);
  font-size: 0.8125rem;
}
.home-section--align-center .home-album-card { align-self: center; }

/* The bookmark the SNS pills are not: a link that is meant to be clicked. */
.home-card {
  align-items: stretch;
  background: var(--surface-raised);
  border: 1px solid var(--border);
  border-radius: var(--home-radius);
  color: inherit;
  display: flex;
  gap: 1rem;
  overflow: hidden;
  text-decoration: none;
  transition: border-color 0.18s var(--ease-out), transform 0.18s var(--ease-out);
}
.home-card:hover {
  border-color: var(--home-accent, var(--accent));
  transform: translateY(-1px);
}
.home-card__image {
  aspect-ratio: 1;
  flex: 0 0 clamp(4.5rem, 12vw, 7rem);
  object-fit: cover;
}
.home-card__body {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  justify-content: center;
  min-width: 0;
  padding: 1rem 1.25rem;
}
.home-card__label { font-weight: 600; }
.home-card__desc {
  color: var(--muted);
  font-size: 0.875rem;
  margin: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.home-card__host {
  color: var(--home-accent, var(--accent));
  font-size: 0.75rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

/* --- Media grid --------------------------------------------------------- */

.home-grid { display: grid; gap: 0.625rem; }
.home-grid--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.home-grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.home-grid--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.home-grid--2 .home-grid__cell img,
.home-grid--3 .home-grid__cell img,
.home-grid--4 .home-grid__cell img { aspect-ratio: 1; object-fit: cover; }

/* Justified: rows of photographs at their own aspect ratio, the way the album
   pages show them. The renderer sets each row's height and each cell's width. */
/* Row widths come from the flex algorithm, not from a measured pixel width:
   growing each cell in proportion to its aspect ratio makes the row fill its
   column exactly, and `aspect-ratio` then gives every cell in the row the same
   height. The renderer emits a string and cannot measure its own column, so
   any pixel width it computed would be a guess with a ragged right edge. */
.home-grid--justified { display: flex; flex-direction: column; gap: 0.625rem; }
.home-grid__row { display: flex; gap: 0.625rem; }
.home-grid__row .home-grid__cell {
  aspect-ratio: var(--ar, 1.5);
  flex: var(--ar, 1.5) 1 0;
}
/* A row holding one photograph has nothing to justify against, so it keeps a
   sane height instead of scaling to the full column width. */
.home-grid__row--single .home-grid__cell {
  flex: 0 0 auto;
  height: clamp(12rem, 26vw, 20rem);
  width: auto;
}
.home-grid__row .home-grid__cell img { height: 100%; object-fit: cover; width: 100%; }

.home-grid__cell {
  border-radius: var(--home-radius);
  display: block;
  overflow: hidden;
}
.home-grid__cell img {
  display: block;
  transition: transform 0.4s var(--ease-out);
  width: 100%;
}
.home-grid__cell:hover img { transform: scale(1.03); }

@media (max-width: 768px) {
  /* Every section collapses to one column, in order. */
  .home-cols { grid-template-columns: 1fr !important; }
  .home-grid--3,
  .home-grid--4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .home-grid__row { flex-wrap: wrap; }
  .home-card { flex-direction: column; }
  .home-card__image { aspect-ratio: 16 / 9; flex-basis: auto; width: 100%; }
  .home-card__body { padding: 0 1.25rem 1.25rem; }
}

@media (prefers-reduced-motion: reduce) {
  .home-button,
  .home-album-link,
  .home-sns__link,
  .home-card,
  .home-grid__cell img { transition: none; }
  .home-button:hover,
  .home-album-link:hover,
  .home-card:hover { transform: none; }
  .home-grid__cell:hover img { transform: none; }
}

/* ---------------------------------------------------------------------------
   Editor chrome. Only ever loaded down the owner branch; every colour rides an
   existing theme token so the editor inherits light/dark like the rest of the
   app -- no new colour literals.
   --------------------------------------------------------------------------- */

/* The page header carries an album's title and its upload button; neither
   means anything over a home document being edited. */
body.home-editing .album-header { display: none; }

/* The toolbar is a status line, not a title bar: no fill, no rule, nothing
   competing with the document under it. Sticky stays, because publish has to
   be reachable from anywhere in a long page. */
.home-toolbar {
  align-items: center;
  backdrop-filter: blur(8px);
  background: color-mix(in srgb, var(--bg) 82%, transparent);
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem;
  justify-content: flex-end;
  padding: 0.4rem 0;
  position: sticky;
  top: 0;
  z-index: 5;
}

/* Ambient feedback, pinned to the bottom edge. In the toolbar it sat between
   the document and the actions with nothing to attach to; here it is where a
   status line belongs and never competes with what is being edited. Empty
   until there is something to say -- :empty keeps a bare pill off the page. */
.home-editor__status {
  background: color-mix(in srgb, var(--bg) 88%, transparent);
  backdrop-filter: blur(8px);
  border: 1px solid var(--border);
  border-radius: 999px;
  bottom: 1rem;
  color: var(--muted);
  font-size: 0.8125rem;
  inset-inline-end: 1.25rem;
  padding: 0.25rem 0.75rem;
  pointer-events: none;
  position: fixed;
  z-index: 6;
}
.home-editor__status:empty { display: none; }

/* One primary action. Everything else is a quiet text control that only draws
   an edge under the pointer. The toolbar builds its buttons as .home-cta, so
   these have to key off that -- .home-editor__btn never appears here. */
.home-toolbar .home-cta { font-size: 0.8125rem; padding: 0.3rem 0.9rem; }
.home-toolbar .home-cta--ghost {
  background: none;
  border-color: transparent;
  color: var(--muted);
  padding-inline: 0.6rem;
}
.home-toolbar .home-cta--ghost:hover {
  background: var(--surface);
  border-color: var(--border);
  color: var(--fg);
}
.home-toolbar__badge {
  color: var(--muted);
  font-size: 0.8125rem;
  padding: 0.3rem 0.7rem;
}

.home-cta {
  background: var(--home-accent, var(--accent));
  border: 1px solid var(--home-accent, var(--accent));
  border-radius: 999px;
  color: inherit;
  cursor: pointer;
  font: inherit;
  padding: 0.4rem 1.1rem;
}

.home-cta--ghost { background: transparent; }

/* A reference block is a block of the document, not a form: no box, no dashed
   outline, nothing the published page would not draw. Its form lives in
   .home-editor__panel below and only opens on focus. */
.home-editor__block {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.home-editor__controls {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.home-editor__field {
  align-items: center;
  display: inline-flex;
  gap: 0.35rem;
}

.home-editor__input,
.home-editor__select {
  background: var(--surface-raised);
  border: 1px solid var(--border);
  border-radius: 6px;
  color: inherit;
  font: inherit;
  padding: 0.3rem 0.5rem;
}

.home-editor__input { flex: 1 1 12rem; }

/* A preview renders through the public renderer, which wraps its block in a
   whole page. Strip the page's own frame so the block sits at its natural
   height inside the column that already spaces it. */
/* A preview renders a whole miniature document, section element and all, and
   custom properties inherit -- so a block inside a section with a photograph
   drew that photograph again behind itself, full width. The preview is a
   picture of one block; it carries no section background of its own. */
.home-editor__preview {
  --home-section-bg: transparent;
  --home-section-image: none;
  min-height: 1.5rem;
}
.home-editor__preview .home-page { padding-bottom: 0; }
.home-editor__preview .home-section__inner { padding-inline: 0; }
.home-editor__hint {
  color: var(--muted);
  font-size: 0.875rem;
  margin: 0;
  opacity: 0.7;
}

.home-editor__hint--inline {
  color: var(--muted);
  font-size: 0.75rem;
  margin-inline-start: 0.5rem;
}

/* A reference block that has nothing to show yet is a slot, not a stray line
   of grey text. This is the one place a dashed edge belongs: it marks what is
   still empty, and it disappears the moment the block resolves. */
.home-editor__preview .home-editor__hint {
  align-items: center;
  border: 1px dashed var(--border);
  border-radius: 8px;
  display: flex;
  justify-content: center;
  min-height: 4.5rem;
  opacity: 1;
  padding: 0.75rem 1rem;
  text-align: center;
}
.home-editor__block:focus-within .home-editor__preview .home-editor__hint {
  border-color: var(--accent);
  color: var(--fg);
}

.home-editor__btn {
  background: transparent;
  border: 1px solid var(--border);
  border-radius: 6px;
  color: inherit;
  cursor: pointer;
  font: inherit;
  padding: 0.3rem 0.7rem;
}

/* A ghost button is an invitation, not a control the eye has to step over. */
.home-editor__btn--ghost {
  border-color: transparent;
  color: var(--muted);
}
.home-editor__btn--ghost:hover { border-color: var(--border); color: var(--fg); }
/* The column-ratio inputs are a number each; without a width they inherit
   .home-editor__input's 12rem flex basis and stretch across the panel. */
.home-editor__span { flex: 0 0 4rem; }

/* Modals: picker, versions, tokens. */
.home-picker,
.home-versions,
.home-tokens {
  align-items: center;
  background: rgba(0, 0, 0, 0.62);
  display: flex;
  inset: 0;
  justify-content: center;
  position: fixed;
  z-index: 50;
}

.home-picker__panel,
.home-versions__panel,
.home-tokens__panel {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  max-height: 85vh;
  max-width: 46rem;
  overflow: auto;
  padding: 1rem;
  width: 90%;
}

.home-picker__tabs {
  align-items: center;
  display: flex;
  gap: 0.5rem;
}
.home-picker__tabs .is-active { border-color: var(--home-accent, var(--accent)); }

/* --- Settings panels -----------------------------------------------------

   Section settings and page settings are rows of one label and one control.
   Laying each row out as its own inline-flex gave every row a different label
   width, so no two controls started at the same x and six rows read as six
   unrelated things. One grid column for the labels lines them all up. */
.home-tokens__panel {
  gap: 0;
  /* Six short rows: the shared 46rem/90% sizing made a settings panel as wide
     as the media picker, with most of it empty. */
  max-width: min(28rem, 92vw);
  padding: 0;
  width: auto;
}
.home-tokens__panel > .home-picker__tabs {
  border-bottom: 1px solid var(--border);
  justify-content: space-between;
  padding: 0.75rem 1.1rem;
}
.home-tokens__panel > .home-editor__field {
  align-items: center;
  display: grid;
  gap: 0.85rem;
  grid-template-columns: 4.5rem 1fr;
  padding: 0.4rem 1.1rem;
}
.home-tokens__panel > .home-editor__field:first-of-type { padding-top: 0.85rem; }
.home-tokens__panel > .home-editor__field:last-child { padding-bottom: 0.95rem; }
.home-tokens__panel > .home-editor__field > span {
  color: var(--muted);
  font-size: 0.8125rem;
}
/* The background picker is the one native select among button groups; give it
   the same height and edge so the column does not look ragged. */
.home-tokens__panel select {
  padding-block: 0.3rem;
}
.home-tokens__panel .home-editor__span { flex: 0 0 3.5rem; width: 3.5rem; }

.home-picker__grid {
  display: grid;
  gap: 0.5rem;
  grid-template-columns: repeat(auto-fill, minmax(6rem, 1fr));
}

.home-picker__item {
  background: transparent;
  border: 1px solid var(--border);
  border-radius: 6px;
  cursor: pointer;
  overflow: hidden;
  padding: 0;
}
/* A list, not a contact sheet. The 6rem columns above are sized for square
   thumbnails; an album row carries a title, and a Korean title in a 6rem box
   wraps to one syllable per line. */
.home-picker__grid--albums { grid-template-columns: 1fr; }

.home-picker__item--album {
  align-items: center;
  color: inherit;
  display: flex;
  gap: 0.5rem;
  justify-content: space-between;
  padding: 0.5rem 0.75rem;
  text-align: left;
}
.home-picker__item--album .home-badge { flex: none; margin-left: 0; white-space: nowrap; }
.home-picker__item img { aspect-ratio: 1; display: block; object-fit: cover; width: 100%; }
.home-picker__item.is-selected { border-color: var(--home-accent, var(--accent)); }
.home-picker__footer { display: flex; justify-content: flex-end; }

.home-versions__body { display: flex; gap: 1rem; }
.home-versions__list { display: flex; flex: 1 1 40%; flex-direction: column; gap: 0.5rem; }
.home-versions__row { align-items: center; display: flex; flex-wrap: wrap; gap: 0.5rem; }
.home-versions__preview { flex: 1 1 60%; }

/* --- Editing chrome ------------------------------------------------------

   The editor mounts the SAME tree the renderer emits, so every layout rule
   above applies to it unchanged. Everything here is chrome laid on top: it
   reveals on hover or keyboard focus, and it never occupies flow, so showing
   it cannot move the text under the pointer. */

.home-editor__sections { display: block; }

.home-editor__section { position: relative; }

/* Each section's inner box is its own stacking context, so a later section
   always paints over an earlier one -- which means a slash menu opened in the
   section above a photo grid disappears behind the photographs. Lift whichever
   section is being worked in above its neighbours. */
.home-editor__section:focus-within { z-index: 4; }

/* No outline on hover. A 1px rectangle drawn tight around a line of text reads
   as an input field, which is exactly the impression a document editor has to
   avoid. The handle appearing is signal enough that the section is live. */

.home-editor__handle {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  /* The handle floats over a photograph as often as over the page background,
     so it needs to read against both. */
  box-shadow: 0 2px 10px rgb(0 0 0 / 0.35);
  display: flex;
  gap: 0.125rem;
  opacity: 0;
  padding: 0.25rem;
  position: absolute;
  /* Pinned to the right edge of the measure, not of the pane: on a wide screen
     the section box runs edge to edge and a handle out there is nowhere near
     the text it belongs to. */
  right: max(0.5rem, calc(50% - var(--home-content-max) / 2 + var(--home-inner-pad)));
  top: 0.5rem;
  transition: opacity 120ms ease;
  z-index: 3;
}
.home-editor__section:hover > .home-editor__handle,
.home-editor__section:focus-within > .home-editor__handle,
.home-editor__handle:focus-within { opacity: 1; }

/* Real hit targets, not text-sized glyphs: these are the only way to reorder,
   configure or remove a section, and they sit over photographs. */
.home-editor__grip,
.home-editor__icon-btn {
  align-items: center;
  background: none;
  border: 0;
  border-radius: 7px;
  color: var(--muted);
  cursor: pointer;
  display: inline-flex;
  height: 2rem;
  justify-content: center;
  padding: 0;
  width: 2rem;
}
.home-editor__grip svg,
.home-editor__icon-btn svg { display: block; }
.home-editor__grip { cursor: grab; touch-action: none; }
.home-editor__grip:active { cursor: grabbing; }
.home-editor__icon-btn:hover,
.home-editor__grip:hover { background: var(--bg); color: var(--fg); }
/* Removing a section throws its blocks away, so it does not look like its
   neighbours once the pointer is on it. */
.home-editor__icon-btn--danger:hover {
  background: color-mix(in srgb, var(--danger, #c0392b) 16%, transparent);
  color: var(--danger, #c0392b);
}
.home-editor__icon-btn:focus-visible,
.home-editor__grip:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* The gap between two sections does two jobs: it shows where one section ends
   and the next begins, and it is where a new one gets inserted. The boundary is
   always drawn, quietly -- without it a page of borderless sections gives the
   owner nothing to aim at. The pointer brings it up to the accent and reveals
   the button. Fixed height, so revealing the button moves nothing. */
.home-editor__insert {
  height: 1.75rem;
  position: relative;
}
.home-editor__insert::before {
  background: var(--border);
  content: "";
  height: 1px;
  /* On the measure, like everything else on the page -- including the inner's
     own inline padding, or the rule overshoots the content by that much and
     the two edges visibly disagree. A rule running the whole width of the pane
     reads as a page break rather than as the seam between two sections. */
  inset: 50% max(0px, calc(50% - var(--home-content-max) / 2 + var(--home-inner-pad))) auto;
  position: absolute;
  transition: background-color 120ms ease;
}
.home-editor__insert:hover::before,
.home-editor__insert:focus-within::before { background: var(--accent); }

.home-editor__insert-btn {
  align-items: center;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 999px;
  color: var(--muted);
  cursor: pointer;
  display: flex;
  font-size: 0.9375rem;
  height: 1.5rem;
  justify-content: center;
  left: 50%;
  line-height: 1;
  opacity: 0;
  padding: 0;
  position: absolute;
  top: 50%;
  transform: translate(-50%, -50%);
  transition: opacity 120ms ease;
  width: 2rem;
}
.home-editor__insert:hover .home-editor__insert-btn,
.home-editor__insert-btn:focus-visible { opacity: 1; }
.home-editor__insert-btn:hover { border-color: var(--accent); color: var(--accent); }

/* The end of the document is not a boundary between two sections, so it draws
   no rule -- the inherited one used to run straight through the button's
   label. */
.home-editor__insert--end {
  display: flex;
  height: auto;
  justify-content: center;
  padding-top: 1.5rem;
}
.home-editor__insert--end::before { content: none; }

/* No dashed box: the column's edge is the text's edge, same as published. */
.home-editor__holder { min-height: 2.5rem; width: 100%; }

/* A reference block publishes its preview and hides its form until the block
   is being worked on. */
.home-editor__block { position: relative; }
/* The form floats over the page, it does not push it. An in-flow panel made
   the document jump every time a block was clicked, and a jumping document is
   the difference between editing a page and filling in a form. */
.home-editor__panel {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: 0 6px 24px rgb(0 0 0 / 0.28);
  display: none;
  flex-wrap: wrap;
  gap: 0.5rem;
  inset-inline-start: 0;
  /* Wider than a narrow column when it has to be: these are text inputs, and
     a URL field in a 300px column is unusable. Bounded so it never leaves the
     viewport on a phone. */
  max-width: min(32rem, calc(100vw - 2rem));
  padding: 0.5rem 0.6rem;
  position: absolute;
  top: calc(100% + 0.4rem);
  width: max-content;
  z-index: 7;
}
/* Focus, not hover: a panel that opens as the pointer crosses the page makes
   the document jump while the owner is only scrolling past it. The block
   itself is focusable, so a click on the preview opens the form. */
.home-editor__block:focus-within .home-editor__panel { display: flex; }

/* A block still waiting on a decision keeps its form open. Hiding it behind
   focus turns an unfinished block into an unlabelled rectangle whose controls
   only appear if the owner guesses to click it -- and until it is finished the
   block is held back from the save, so there is nothing to keep quiet about. */
/* In the flow, unlike the floating one: this panel stays open until the block
   is finished, and a form that never closes would sit on top of whatever comes
   next. */
.home-editor__block--setup .home-editor__panel {
  box-shadow: none;
  display: flex;
  margin-top: 0.4rem;
  max-width: 100%;
  position: static;
  width: auto;
}
.home-editor__block--setup .home-editor__preview .home-editor__hint {
  border-color: color-mix(in srgb, var(--accent) 55%, var(--border));
  color: var(--fg);
}

.home-editor__block:focus { outline: none; }
.home-editor__block:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; }

/* Block reordering. The grip is the vendor's, the gesture is ours: it draws a
   line where the block would land and dims the one being moved. */
.home-editor__holder .ce-block.home-editor__drop {
  box-shadow: 0 -2px 0 -1px var(--home-accent, var(--accent));
}
.home-editor__holder .ce-block.home-editor__drop--after {
  box-shadow: 0 2px 0 -1px var(--home-accent, var(--accent));
}
.home-editor__holder .ce-block.home-editor__block--dragging { opacity: 0.4; }
.home-editor__holder .ce-toolbar__settings-btn { cursor: grab; touch-action: none; }
.home-editor__holder .ce-toolbar__settings-btn:active { cursor: grabbing; }

/* A preview is a picture of the published block, not the block. Following a
   link card's href from inside the editor would abandon the page being
   edited, and the click has to reach the wrapper to open the form. */
.home-editor__preview a { pointer-events: none; }

/* Settings that take three or four values: a row of pressed buttons shows the
   current one without opening anything. */
.home-editor__choice { display: flex; gap: 0.25rem; }
.home-editor__choice-btn {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 6px;
  color: var(--muted);
  cursor: pointer;
  font-size: 0.8125rem;
  padding: 0.25rem 0.55rem;
}
.home-editor__choice-btn[aria-pressed="true"] {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--bg);
}

.home-editor__section--dragging { opacity: 0.55; }

/* --- Editor.js overrides -------------------------------------------------

   Every rule that fights the vendored bundle lives here, in one place, so the
   specificity contest is visible rather than scattered. Never edit the vendor
   file itself. */

/* The core reserves `minHeight` px of padding here as a click target: clicking
   below the last block appends a paragraph. Side-by-side columns cannot afford
   that -- it is dead space at the foot of every one of them, and the published
   page has none of it. The editor keeps a real empty paragraph at the end of
   each column instead (`ensureTrailingParagraph`), which is the same
   affordance and takes the space it actually occupies. */
.home-editor__holder .codex-editor__redactor { padding-bottom: 0 !important; }
.home-editor__holder .ce-block__content,
.home-editor__holder .ce-toolbar__content {
  margin: 0;
  max-width: none;
}

/* The published page's vertical rhythm, restated against Editor.js's DOM. The
   published rules key off .home-block--<type>; here the block type has to be
   read off what the tool rendered, so a text block is one with a .ce-paragraph
   and a heading is one with an h1/h2/h3. Everything else is a media block.
   Same four tokens, same precedence order:

       default -> tight -> media -> heading

   Specificity does the ordering here rather than source order, because :has()
   takes the weight of its heaviest argument; the selectors are written so the
   heavier rule is also the one that should win. */
.home-editor__holder .ce-block + .ce-block { margin-top: var(--home-flow); }
.home-editor__holder .ce-block:has(.ce-paragraph) + .ce-block:has(.ce-paragraph),
.home-editor__holder .ce-block:has(h1, h2, h3) + .ce-block {
  margin-top: var(--home-flow-tight);
}
.home-editor__holder
  .ce-block
  + .ce-block:not(:has(.ce-paragraph)):not(:has(h1)):not(:has(h2)):not(:has(h3)) {
  margin-top: var(--home-flow-loose);
}
.home-editor__holder .ce-block + .ce-block:has(h1, h2, h3) {
  margin-top: var(--home-flow-heading);
}
.home-editor__holder .ce-block:first-child { margin-top: 0; }
/* Editor.js pins the block handles to the right of the block below its own
   width threshold, which every column here is under. They belong in the left
   gutter, where the eye looks for them and where they do not sit inside the
   sentence being written. */
.home-editor__holder .ce-toolbar__actions {
  left: -3.4rem;
  padding-right: 0;
  right: auto;
}
/* A column mounted before the stylesheet settled keeps the vendor's 50px
   right margin for good, because the --narrow measurement runs once at
   construction. Neutralise it rather than depend on that ordering. */
.home-editor__holder .codex-editor--narrow .codex-editor__redactor { margin-right: 0; }

/* Every reference block sets position:relative to carry its panel, so a block
   further down the column paints over the toolbar -- and the slash menu opened
   above a photo grid vanishes behind the photographs. The toolbar is chrome
   over the column, so it says so. This stays inside .codex-editor's own
   stacking context and cannot reach past the column it belongs to.

   It also has to clear the block's own panel (z-index 7). A block whose panel
   was open painted it over the tune menu that had just been opened beside it,
   so "삭제" was a target you could see and not click -- and a photo, a grid or
   a quote could not be removed through its menu at all. */
.home-editor__holder .ce-toolbar { z-index: 8; }

/* Same race one level up: two columns are siblings, so the right column paints
   over a menu opened in the left one. */
.home-col:focus-within { z-index: 2; }

.home-editor__holder .ce-toolbar__plus,
.home-editor__holder .ce-toolbar__settings-btn { color: var(--muted); }
.home-editor__holder .ce-toolbar__plus:hover,
.home-editor__holder .ce-toolbar__plus--active,
.home-editor__holder .ce-toolbar__settings-btn:hover,
.home-editor__holder .ce-toolbar__settings-btn--active {
  background-color: var(--surface);
  /* The vendor's narrow-screen rules give these a white chip with a border and
     a shadow, which is a light-theme artefact on every dark page. */
  border: 0;
  box-shadow: none;
  color: var(--fg);
}

/* The popover paints nothing on .ce-popover itself: every colour lives on
   .ce-popover__container and reaches it through these custom properties.
   Setting `background` on .ce-popover therefore paints the wrong element and
   leaves the slash menu white-on-white in dark mode. Redefine the properties
   instead and let the vendor's own rules do the painting. */
.home-editor__holder .ce-popover {
  --color-background: var(--surface);
  --color-border: var(--border);
  --color-text-primary: var(--fg);
  --color-text-secondary: var(--muted);
  --color-background-item-hover: var(--bg);
  --color-background-item-focus: color-mix(in srgb, var(--accent) 18%, transparent);
  --color-background-item-confirm: var(--accent);
}
/* The vendor's 200px is sized for one-word English tool names; every Korean
   label here was being clipped mid-word. */
.home-editor__holder .ce-popover__container { min-width: 15rem; }
.home-editor__holder .ce-popover-item__title { overflow: visible; }
/* Room to read: the vendor packs the rows tight enough that eleven Korean
   labels read as one block of text. */
.home-editor__holder .ce-popover-item { padding: 0.3rem 0.45rem; }
.home-editor__holder .ce-popover-item__icon {
  background: var(--bg);
  border: 1px solid var(--border);
  box-shadow: none;
  color: var(--muted);
}
.home-editor__holder .ce-popover-item:hover .ce-popover-item__icon,
.home-editor__holder .ce-popover-item--focused .ce-popover-item__icon { color: var(--fg); }

.home-editor__holder .cdx-search-field {
  background: var(--bg);
  border: 1px solid var(--border);
  color: var(--fg);
}
.home-editor__holder .cdx-search-field__input::placeholder,
.home-editor__holder .cdx-search-field__icon svg { color: var(--muted); }

/* The fallback panel an owner sees when a document holds a tool this build no
   longer has. It must stay legible on the theme it appears in. */
.home-editor__holder .ce-stub {
  background: var(--surface);
  border: 1px solid var(--border);
  color: var(--muted);
}

/* .ce-inline-toolbar is a transparent positioning wrapper -- the panel it
   shows is a nested popover. Painting the wrapper draws an empty bordered box
   pinned to the top-left of every column, permanently. */
.home-editor__holder .ce-inline-toolbar {
  background: none;
  border: 0;
}

/* Selection colours are hardcoded light-blue in the bundle. */
.home-editor__holder .ce-block--selected .ce-block__content {
  background: color-mix(in srgb, var(--accent) 16%, transparent);
}
.home-editor__holder .codex-editor ::selection {
  background-color: color-mix(in srgb, var(--accent) 30%, transparent);
}

/* The vendor pads every text block by 0.4em, which the rhythm table above then
   adds to: two paragraphs stood a tight margin plus two paddings apart while
   the published page had only the margin. Spacing comes from exactly one
   place. */
.home-editor__holder .cdx-block { padding-block: 0; }

/* Our two inline tools draw their own buttons; the vendor's are styled by its
   own stylesheet and ours have to sit in the same row without looking bolted
   on. */
.home-editor__holder .ce-inline-tool {
  align-items: center;
  background: transparent;
  border: 0;
  border-radius: 4px;
  color: inherit;
  cursor: pointer;
  display: inline-flex;
  height: 34px;
  justify-content: center;
  padding: 0;
  width: 34px;
}
.home-editor__holder .ce-inline-tool:hover {
  background: color-mix(in srgb, currentColor 10%, transparent);
}
.home-editor__holder .ce-inline-tool--active { color: var(--home-accent, var(--accent)); }

/* Inline code is a literal, so it says so in the page's own monospace rather
   than by colour alone. */
.home-paragraph code,
.home-header code,
.home-quote code,
.home-list code,
.home-editor__holder code {
  background: color-mix(in srgb, currentColor 8%, transparent);
  border-radius: 4px;
  font-family: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
  font-size: 0.9em;
  padding: 0.1em 0.35em;
}

/* A list is the one block that edits in place: the published markup with its
   text spans made editable. There is no second stylesheet, so it cannot drift
   from the page. */
.home-editor__list .home-list__text:focus { outline: none; }
.home-editor__list .home-list__text:empty::after {
  color: var(--muted);
  content: "";
  /* A zero-width space, so an empty item still has a line box to click. */
  white-space: pre;
}
.home-editor__list .home-list__mark { cursor: pointer; }
.home-editor__list .home-list--checklist .home-list__mark:hover {
  border-color: var(--home-accent, var(--accent));
}

/* An empty block has to be visible, or a block editor looks like it merely got
   taller when you press Enter. The vendor only paints its placeholder on a
   block that is literally :empty or the document's only one -- a new block
   holds a <br>, so neither matched and every empty block after the first was
   invisible. Ours keys off data-empty, which Editor.js does keep current. */
.home-editor__holder .ce-paragraph[data-placeholder-active][data-empty="true"]::before {
  color: var(--muted);
  content: attr(data-placeholder-active);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.12s ease;
}
/* Every column now ends in an empty paragraph, so a hint painted on all of them
   at once turns a three-column section into three lines of instructions. It
   belongs to the line the owner is on, or to the column the pointer is over --
   nowhere else. */
.home-editor__holder:hover
  .ce-paragraph[data-placeholder-active][data-empty="true"]::before {
  opacity: 0.35;
}
/* An empty column is the one place the hint has to stand on its own: there is
   nothing else in it to explain what the column is for. */
.home-editor__holder
  .ce-block:only-child
  .ce-paragraph[data-placeholder-active][data-empty="true"]::before {
  opacity: 0.35;
}
.home-editor__holder .ce-paragraph[data-empty="true"]:focus::before { opacity: 0.8; }

/* Editor.js writes its own heading element, so the published type scale has to
   reach it by tag rather than by class. */
.home-editor__holder h1,
.home-editor__holder h2,
.home-editor__holder h3 {
  font-size: var(--home-display-size);
  font-weight: var(--home-display-weight);
  letter-spacing: var(--home-display-tracking);
  line-height: var(--home-display-leading);
  margin: 0;
}
.home-editor__holder h3 { font-size: calc(var(--home-display-size) * 0.62); }
.home-editor__holder .ce-paragraph {
  font-size: var(--home-body-size);
  line-height: var(--home-body-leading);
}

/* Touch and coarse pointers have no reliable hover, so hover-only chrome must
   stay visible and settings panels must sit in the document flow. Desktop hover
   UX is unchanged outside this query. */
@media (hover: none), (pointer: coarse) {
  .home-editor__handle,
  .home-editor__insert-btn {
    opacity: 1;
    pointer-events: auto;
  }
  /* Section seams stay visible so insert targets are aimable without hover. */
  .home-editor__insert::before { background: var(--accent); }

  /* Editor.js hides block grips until the toolbar opens; keep them reachable. */
  .home-editor__holder .ce-toolbar__actions {
    opacity: 1;
    pointer-events: auto;
    touch-action: none;
  }

  /* Empty-block hints cannot wait for a column hover on touch. */
  .home-editor__holder
    .ce-paragraph[data-placeholder-active][data-empty="true"]::before {
    opacity: 0.35;
    pointer-events: none;
  }

  /* On touch the panel is always shown, so it goes back into the flow -- a
     floating form that never closes would cover the block below it. */
  .home-editor__block .home-editor__panel {
    background: none;
    border: 0;
    box-shadow: none;
    display: flex;
    margin-top: 0.5rem;
    max-width: 100%;
    padding-inline: 0;
    pointer-events: auto;
    position: static;
    width: auto;
  }
}

@media (prefers-reduced-motion: reduce) {
  .home-editor__handle,
  .home-editor__insert::before,
  .home-editor__insert-btn { transition: none; }
}

/* The bookmark's meta line: favicon and site name, above the title. */
.home-card__meta {
  display: flex;
  align-items: center;
  gap: 6px;
}

.home-card__icon {
  width: 16px;
  height: 16px;
  border-radius: 4px;
  object-fit: cover;
}

/* Text left, thumbnail right -- the card reads as a line of prose with a
   picture attached, not a picture with a caption. The base .home-card rule
   above already sets display/align/gap; only the order changes here. */
.home-card {
  justify-content: space-between;
}

/* The body's padding was written for a picture on the LEFT, which is why its
   left side was flush against the border once the picture moved. It is
   symmetric now, and the side the picture sits on gives its padding back so
   the image still reaches the card's edge. */
.home-card__body {
  padding: 1rem 1.25rem;
}

.home-card:has(.home-card__image) .home-card__body {
  padding-right: 0;
}

/* A flex item will not shrink below its own intrinsic width unless told to, and
   a fetched og:image is routinely 1200px wide -- it pushed the whole card open
   and squeezed the text into a one-letter column. Album thumbnails were small
   enough that this never showed. */
.home-card__image {
  min-width: 0;
}

/* One line, no picture: a link that happens to know its own name. */
.home-card--inline {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 6px 10px;
}

.home-card--inline .home-card__label {
  font-size: 0.95rem;
}


/* Two authoring tabs: an external address and an internal album are different
   questions and stop sharing a row. */
.home-bookmark__tabs {
  display: flex;
  gap: 4px;
  margin-bottom: 8px;
}

.home-bookmark__tab {
  padding: 4px 10px;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: inherit;
  font: inherit;
  font-size: 0.85rem;
  opacity: 0.65;
  cursor: pointer;
}

.home-bookmark__tab.is-current {
  opacity: 1;
  background: rgba(127, 127, 127, 0.18);
}

.home-bookmark__url {
  flex: 1 1 auto;
}

/* Collapsed by default: the fetch fills these in, and most bookmarks never
   need them opened. */
.home-bookmark__fields > summary {
  cursor: pointer;
  font-size: 0.85rem;
  opacity: 0.75;
}

.home-editor__btn.is-current {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}
