/* ==========================================================================
   Lexxy Editor Extensions

   Custom extensions to Lexxy editor styling for Pluto's warm paper aesthetic.
   Lexxy provides base editor/content CSS via the gem — don't modify those.
   ========================================================================== */

/* Override Lexxy's default blue accent with pluto's warm parchment palette.
   Set at :root so it applies to both the editor and display-mode content. */
:root {
  --lexxy-color-accent-dark: var(--parchment-dark);
  --lexxy-color-accent-medium: var(--parchment);
  --lexxy-color-accent-light: var(--parchment-light);
  --lexxy-color-accent-lightest: var(--paper-texture);
  --lexxy-color-link: var(--parchment-dark);
}

/* Reset inherited line-height so Lexxy's lh-based sizing works correctly */
lexxy-editor {
  line-height: normal;
}

/* Indent lists so markers (bullets/numbers) don't overlap text */
lexxy-editor ul,
lexxy-editor ol {
  padding-inline-start: 1.5em;
}

/* Lexxy uses :where() selectors (zero specificity) for its toolbar button
   styles, including `display: grid; place-items: center`.  normalize.css
   sets `summary { display: list-item }` at normal specificity, which wins
   for the two dropdown triggers (color highlight, link) whose <summary>
   elements carry .lexxy-editor__toolbar-button.  Re-apply the grid layout
   and suppress the disclosure marker so they match the regular buttons. */
lexxy-editor summary.lexxy-editor__toolbar-button {
  display: grid;
  place-items: center;
  list-style: none;
}

lexxy-editor summary::-webkit-details-marker {
  display: none;
}

/* Lexxy's default max-inline-size: 40ch on the dropdown content is too
   narrow to fit 9/10 color buttons at 2lh each. Likely an upstream bug.
   48ch fits all buttons comfortably. */
.lexxy-editor__toolbar-dropdown-content {
  max-inline-size: 48ch;
}

/* ==========================================================================
   Focus Highlight

   The global *:focus-visible puts a thick outline on the inner contenteditable
   div, which looks wrong (only highlights the text area, not the toolbar).
   Instead, highlight the whole lexxy-editor element on focus-within.
   ========================================================================== */

lexxy-editor:focus-within {
  outline: 3px solid var(--parchment-dark);
  outline-offset: 2px;
  border-radius: var(--border-radius);
}

/* Suppress the global focus-visible outline on the inner contenteditable */
lexxy-editor .lexxy-editor__content:focus-visible {
  outline: none;
  box-shadow: none;
}

/* ==========================================================================
   Rich Text Content Display

   Styles for rendered Action Text content (display mode, not editing).
   These apply to the .rich-text-content wrapper from action_text/contents.
   ========================================================================== */

.rich-text-content {
  line-height: 1.5;
  overflow-wrap: break-word;
  word-break: break-word;
}

.rich-text-content * {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

.rich-text-content h1 {
  font-size: 1.2em;
  line-height: 1.2;
}

.rich-text-content blockquote {
  border: 0 solid var(--parchment-dark);
  border-left-width: 0.3em;
  margin-left: 0.3em;
  padding-left: 0.6em;
}

.rich-text-content ul,
.rich-text-content ol {
  padding-left: 1.5em;
  margin: 0.25em 0;
}

.rich-text-content li {
  margin-left: 0;
}

.rich-text-content pre {
  display: inline-block;
  width: 100%;
  vertical-align: top;
  font-family: monospace;
  font-size: 0.9em;
  padding: 0.5em;
  white-space: pre;
  background-color: rgba(0, 0, 0, 0.05);
  overflow-x: auto;
}

.rich-text-content img {
  max-width: 100%;
  height: auto;
}

.rich-text-content .attachment {
  display: inline-block;
  position: relative;
  max-width: 100%;
}

.rich-text-content .attachment a {
  color: inherit;
  text-decoration: none;
}

.rich-text-content .attachment__caption {
  text-align: center;
}

/* ==========================================================================
   Checklist Rendering

   Lexical check lists render as <ul __lexicallisttype="check"> with
   <li role="checkbox" aria-checked="true|false"> items. CSS renders the
   visual checkboxes via ::before pseudo-elements — no <input> elements.
   Styles apply in both the editor and display mode.
   ========================================================================== */

/* Target checklist <ul> via :has() since the __lexicalListType attribute
   is a JS DOM property in the editor (not an HTML attribute), so attribute
   selectors don't match. In display mode (ActionText), it IS serialized as
   an HTML attribute. Using :has(li[role="checkbox"]) covers both cases. */
lexxy-editor ul:has(> li[role="checkbox"]),
.rich-text-content ul:has(> li[role="checkbox"]),
.rich-text-content ul[__lexicallisttype="check"] {
  list-style: none;
  padding-inline-start: 0;
  margin: var(--space-xs) 0;
}

lexxy-editor li[role="checkbox"],
.rich-text-content li[role="checkbox"] {
  display: flex;
  align-items: flex-start;
  gap: var(--space-sm);
  cursor: pointer;
  padding: var(--space-xs) 0;
}

lexxy-editor li[role="checkbox"]::before,
.rich-text-content li[role="checkbox"]::before {
  content: "";
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.1em;
  height: 1.1em;
  min-width: 1.1em;
  margin-top: 0.15em;
  border: 2px solid var(--parchment-dark);
  border-radius: var(--border-radius);
  background: var(--bg-white-full, rgba(255, 255, 255, 0.9));
  transition: background var(--transition-base), border-color var(--transition-base);
}

lexxy-editor li[aria-checked="true"]::before,
.rich-text-content li[aria-checked="true"]::before {
  content: "✓";
  background-color: var(--parchment-dark);
  border-color: var(--parchment-dark);
  color: white;
  font-size: 0.8em;
  font-weight: var(--font-weight-bold);
}

lexxy-editor li[aria-checked="true"],
.rich-text-content li[aria-checked="true"] {
  text-decoration: line-through;
  opacity: var(--opacity-semi);
}

/* ==========================================================================
   Auto-Save Status Indicator

   Shows save state as a floating indicator in the bottom-right of the editor:
   - Hidden when clean (no pending changes)
   - Animated dots when dirty/saving
   - Static green dots on success, then fades out
   - Static red dots on error
   - Click-through (pointer-events: none) to not interfere with editing
   ========================================================================== */

/* Positioning context for the save indicator */
.has-autosave-indicator {
  position: relative;
}

.autosave-progress-indicator {
  position: absolute;
  bottom: 0.75em;
  right: 0.75em;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2em;
  height: 2em;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity var(--transition-base), visibility var(--transition-base);
}

/* Indicator icon - uses currentColor so we set color property */
.autosave-progress-indicator-icon {
  width: 1.5em;
  height: 1.5em;
  color: var(--ink-medium);
  transition: color var(--transition-base);
}

/* --------------------------------------------------------------------------
   3-Dot Pulse Animation (based on svg-spinners by n3r4zzurr0)
   Uses transform: scale() for better browser support than animating r attribute
   -------------------------------------------------------------------------- */

@keyframes autosave-dot-pulse {
  0%, 100% {
    transform: scale(1);
  }
  50% {
    transform: scale(0.2);
  }
}

/* Set transform-origin for each dot (cx values from SVG viewBox) */
.autosave-dot-1 {
  transform-origin: 4px 12px;
}

.autosave-dot-2 {
  transform-origin: 12px 12px;
}

.autosave-dot-3 {
  transform-origin: 20px 12px;
}

/* --------------------------------------------------------------------------
   State: Dirty / Saving (animated dots)
   -------------------------------------------------------------------------- */

.autosave-progress-indicator-dirty {
  opacity: 1;
  visibility: visible;
}

.autosave-progress-indicator-dirty .autosave-dot {
  animation: autosave-dot-pulse 0.8s ease-in-out infinite;
}

.autosave-progress-indicator-dirty .autosave-dot-2 {
  animation-delay: -0.53s;
}

.autosave-progress-indicator-dirty .autosave-dot-3 {
  animation-delay: -0.27s;
}

/* --------------------------------------------------------------------------
   State: Success (green dots expand then fade out)
   -------------------------------------------------------------------------- */

@keyframes autosave-dot-success {
  0% {
    transform: scale(1);
    opacity: 1;
  }
  50% {
    transform: scale(1.4);
    opacity: 1;
  }
  100% {
    transform: scale(1.6);
    opacity: 0;
  }
}

.autosave-progress-indicator-success {
  opacity: 1;
  visibility: visible;
}

.autosave-progress-indicator-success .autosave-progress-indicator-icon {
  color: var(--color-success-muted);
}

.autosave-progress-indicator-success .autosave-dot {
  animation: autosave-dot-success 0.6s ease-out forwards;
}

.autosave-progress-indicator-success .autosave-dot-2 {
  animation-delay: 0.05s;
}

.autosave-progress-indicator-success .autosave-dot-3 {
  animation-delay: 0.1s;
}

/* --------------------------------------------------------------------------
   State: Error (red, with tooltip)
   -------------------------------------------------------------------------- */

.autosave-progress-indicator-error {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  cursor: help;
}

.autosave-progress-indicator-error .autosave-progress-indicator-icon {
  color: var(--ink-dark);
  animation: none;
}
