/*
 * Styles for the editable content of <l-prose-editor>.
 *
 * The ProseMirror editable element is rendered in light DOM (slotted), not the
 * shadow root, to work around contenteditable caret/selection bugs in Firefox
 * and WebKit inside shadow trees. So its styles live in this published CSS file
 * rather than the element's shadow styles. Import once globally:
 *
 *   @import 'luxen-ui/css/prose-editor';
 */
@layer components {
  l-prose-editor .ProseMirror {
    padding: var(--content-padding, 0.75rem 1rem);
    min-height: var(--content-min-height, 8rem);

    /* The UA ring on the contenteditable is replaced by the frame ring below —
       it would render square (this element has no radius) and only around the
       content, not the toolbar. */
    outline: none;
  }

  /* Focus: the editor frame border takes the focus-ring color, matching
     l-input / l-textarea. `:has(.ProseMirror:focus-visible)`, not
     `:focus-within` — a focused toolbar button shows its own ring, not the
     field's (same rule as the l-input adornment group).
     The shadow stylesheet can't express this: `.ProseMirror` is slotted light
     DOM, and `:has()` inside `:host()` does not match. Hence ::part().
     Both halves flip together so the collapsed edge shared by toolbar and
     editor stays one continuous color.
     border-color, not an outline: it follows --border-radius (including the
     toolbar-placement corner collapsing) and can never be clipped by a
     consumer ancestor with `overflow: hidden`. That makes the border the
     primary layer; the soft halo below is the second one, exactly as in
     input.css / textarea.css.
     The fallback matters: this stylesheet ships separately from the element's
     shadow styles that define --border-color-focus, so a consumer pairing
     mismatched CSS/JS versions would otherwise hit an undefined variable —
     border-color then resets to currentColor and the frame takes the text
     color instead of the ring. */
  l-prose-editor:has(.ProseMirror:focus-visible)::part(toolbar),
  l-prose-editor:has(.ProseMirror:focus-visible)::part(editor) {
    border-color: var(--border-color-focus, var(--l-focus-ring));
  }

  /* Soft focus halo — same recipe as input.css / textarea.css, so a prose
     editor and a textarea are indistinguishable when focused. On the wrapper,
     not on toolbar/editor: one halo around the whole frame, otherwise the two
     halves would each cast one along the edge they share. An ancestor with
     `overflow: hidden` clips this, which is why it is the second layer and not
     the only one — clipped, the border above still reads as focus.

     The transparent outline keeps a visible indicator under forced colors,
     where border-color is overridden by the user's palette and the border rule
     stops reading as a state change. Inset (negative offset), unlike
     input.css / textarea.css: under forced colors it is the only indicator
     left, so it must survive that same clipping. */
  l-prose-editor:has(.ProseMirror:focus-visible)::part(wrapper) {
    outline: 2px solid transparent;
    outline-offset: -2px;
    box-shadow: 0 0 0 3px
      color-mix(in oklab, var(--border-color-focus, var(--l-focus-ring)) 22%, transparent);
  }

  l-prose-editor .ProseMirror :first-child {
    margin-top: 0;
  }

  l-prose-editor .ProseMirror :last-child {
    margin-bottom: 0;
  }

  /* Block spacing & typography — baseline so content reads correctly without a
     typography framework. A consumer's `prose` class (e.g. Tailwind Typography)
     layers on top via the higher-priority utilities layer. */
  l-prose-editor .ProseMirror p {
    margin-block: 0.5em;
  }

  l-prose-editor .ProseMirror :is(h1, h2, h3, h4) {
    margin-block: 1em 0.5em;
    font-weight: 600;
    line-height: 1.25;
  }

  l-prose-editor .ProseMirror h1 {
    font-size: 1.5em;
  }

  l-prose-editor .ProseMirror h2 {
    font-size: 1.3em;
  }

  l-prose-editor .ProseMirror h3 {
    font-size: 1.15em;
  }

  l-prose-editor .ProseMirror :is(ul, ol) {
    margin-block: 0.5em;
    padding-inline-start: 1.5rem;
  }

  l-prose-editor .ProseMirror ul {
    list-style: disc;
  }

  l-prose-editor .ProseMirror ol {
    list-style: decimal;
  }

  l-prose-editor .ProseMirror li {
    margin-block: 0.25em;
  }

  /* Placeholder — Tiptap Placeholder extension */
  l-prose-editor .ProseMirror p.is-editor-empty:first-child::before {
    content: attr(data-placeholder);
    float: inline-start;
    height: 0;
    color: var(--placeholder-color, var(--l-color-text-tertiary));
    pointer-events: none;
  }

  /* Highlight mark */
  l-prose-editor .ProseMirror mark {
    border-radius: 0.2em;
    background-color: var(--l-color-bg-fill-warning-subtle);
    -webkit-box-decoration-break: clone;
            box-decoration-break: clone;
  }

  /* Links */
  l-prose-editor .ProseMirror a {
    color: var(--l-color-text-info);
    text-decoration: underline;
    cursor: pointer;
  }

  /* Blockquote */
  l-prose-editor .ProseMirror blockquote {
    border-inline-start: 3px solid var(--l-color-border);
    padding-inline-start: 1rem;
    color: var(--l-color-text-secondary);
  }

  /* Inline code & code blocks */
  l-prose-editor .ProseMirror code {
    border-radius: 0.25rem;
    padding: 0.125em 0.3em;
    background-color: var(--l-color-bg-fill-neutral-subtle);
    font-size: 0.9em;
  }

  l-prose-editor .ProseMirror pre {
    border-radius: var(--l-radius-md);
    padding: 0.75rem 1rem;
    background-color: var(--l-color-bg-fill-neutral-subtle);
    overflow-x: auto;
  }

  l-prose-editor .ProseMirror pre code {
    padding: 0;
    background: none;
  }

  /* Horizontal rule */
  l-prose-editor .ProseMirror hr {
    margin-block: 1rem;
    border: none;
    border-top: 1px solid var(--l-color-divider);
  }

  l-prose-editor .ProseMirror hr.ProseMirror-selectednode {
    border-top-color: var(--l-focus-ring);
  }
}
