@layer components {
  /* THE BLANK SLATE — an invitation to fill something in.

     Basecamp's version puts a hand-drawn sketch of the filled state inside
     each empty card. Gather renders the real partial with placeholder data
     instead and ghosts it here, so the preview is drawn by the same code as
     the real thing and cannot drift.

     Sketch and note share one grid cell. The sketch stretches to whatever
     height the ghosted component wants; the note sits centered on top of it.
     That way a slate holding one ghost ride and a slate holding six ghost
     roster rows both work without hardcoding a height anywhere. */

  .blank-slate {
    position: relative;
    display: grid;
    isolation: isolate;
    min-height: 190px;
    padding: 22px;
    /* The dash is the whole point — it is what says "temporary, and yours to
       replace". At --paper-edge on warm paper it was invisible and the slate
       read as a permanent card. Mixed off --ink-faint so it stays a hairline
       in both schemes without being a hard line. */
    border: 1.5px dashed color-mix(in oklab, var(--ink-faint) 60%, transparent);
    border-radius: var(--radius-lg);
    background: var(--paper-warm);
    overflow: hidden;
  }

  .blank-slate-sketch,
  .blank-slate-note {
    grid-area: 1 / 1;
  }

  /* The ghost. Grayscale kills the component's own colour so a ghosted ride
     never looks like a real ride someone could act on; the blur and low
     opacity push it behind the note without needing a scrim over the top.
     pointer-events on the wrapper because `inert` is not everywhere yet. */
  .blank-slate-sketch {
    align-self: stretch;
    display: grid;
    place-items: center;
    /* No blur: on a line drawing it reads as muddy rather than soft, and the
       low opacity already does the work of pushing it behind the words. */
    filter: grayscale(1) contrast(0.6) opacity(0.26);
    pointer-events: none;
    user-select: none;
    -webkit-user-select: none;

    /* Fade the ghost out toward the bottom edge so it reads as a sketch
       trailing off rather than a real component someone clipped in half. */
    mask-image: linear-gradient(to bottom, #000 0%, #000 45%, transparent 100%);
    -webkit-mask-image: linear-gradient(to bottom, #000 0%, #000 45%, transparent 100%);
  }

  /* The landscape wireframe. Capped rather than stretched: the band takes
     its height from the organizer's hero setting, which can be 640px, and a
     line drawing scaled to that reads as a diagram instead of a sketch. */
  .sketch-landscape {
    display: block;
    width: min(100%, 420px);
    max-height: 190px;
    color: var(--ink);
  }

  /* A ghost must never be reachable. Belt and braces over `inert`. */
  .blank-slate-sketch a,
  .blank-slate-sketch button,
  .blank-slate-sketch input,
  .blank-slate-sketch select,
  .blank-slate-sketch textarea {
    pointer-events: none;
  }

  .blank-slate-note {
    position: relative;
    z-index: 1;
    align-self: center;
    justify-self: center;
    max-width: 42ch;
    text-align: center;
  }

  .blank-slate-headline {
    margin: 0;
    font-family: var(--display, inherit);
    font-size: 18px;
    font-weight: var(--weight-bold, 700);
    line-height: 1.3;
    color: var(--ink);
    text-wrap: balance;
  }

  .blank-slate-body {
    margin: 7px 0 0;
    font-size: 14.5px;
    line-height: 1.55;
    color: var(--ink-soft);
    text-wrap: pretty;
  }

  /* "As your project grows, you'll be able to add things via this same menu."
     The sentence that tells you the hint is temporary and where the real
     control lives once it's gone. Quieter than the body on purpose. */
  .blank-slate-later {
    margin: 7px 0 0;
    font-size: 13px;
    line-height: 1.5;
    color: var(--ink-faint);
  }

  .blank-slate-action {
    margin-top: 15px;
  }

  /* Compact: a slate living inside an existing card, where the card already
     supplies the frame and a second heavy border would read as a box in a
     box. Lighter edge, no ghost height floor. */
  .blank-slate--compact {
    min-height: 0;
    padding: 18px 16px;
    border-radius: var(--radius-md);
    background: transparent;
  }

  .blank-slate--compact .blank-slate-headline { font-size: 16px; }
  .blank-slate--compact .blank-slate-body { font-size: 14px; }

  @media (max-width: 600px) {
    .blank-slate {
      min-height: 165px;
      padding: 18px 14px;
    }
    .blank-slate-headline { font-size: 17px; }
    .blank-slate-body { font-size: 14px; }
  }

  /* Reduced transparency: drop the ghost entirely rather than serve a
     half-legible smear behind the words. The note still says everything
     that matters, which is the test for whether the ghost was decoration. */
  @media (prefers-reduced-transparency: reduce) {
    .blank-slate-sketch { display: none; }
  }
}
