/*
 * Credit-pack purchase page: pack list cards, special-pack highlight, prices, icons, light-mode variants (all scoped to body[x-data='packs']).
 *
 * Moved from public_html/assets/css/doona-packs.css lines 1–179 (asset
 * migration, Phase A); since then reworked for the borderless elevation
 * design (DESIGN-ELEVATION.md): fills instead of rims/outlines.
 * Its position in index.css is part of the cascade; move it only together
 * with a reorder-safety check.
 */
body[x-data='packs'] main.flex.flex-col.gap-5.pb-20 > div > p {
  margin-top: 13px;
}
body[x-data='packs']
  main.flex.flex-col.gap-5.pb-20
  div[class='group/list']
  > ul {
  gap: 15px;
}
body[x-data='packs'] p.mt-4.text-xs.text-content-dimmed {
  margin: 30px 0 !important;
}
/* [Doona] - Elevation (DESIGN-ELEVATION.md): the cards keep the global .box
   group fill. They were #151618 / #ffffff, which on the page canvas left a
   card with no visible shape once its rim was removed. */
body[x-data='packs'] ul.flex.flex-col.gap-1.mt-3 {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
}
@media (max-width: 768px) {
  body[x-data='packs'] ul.flex.flex-col.gap-1.mt-3 {
    grid-template-columns: repeat(2, 1fr);
  }
}
@media (max-width: 500px) {
  body[x-data='packs'] ul.flex.flex-col.gap-1.mt-3 {
    grid-template-columns: 1fr;
  }
}

/* [Doona] - No overflow:hidden (it clipped the keyboard focus ring of the
   card link); the brand layer below rounds itself instead. Hover is the
   .box fill step (the card carries hover:border-line), never a scale of the
   whole card; press settles to .98 on pointer-down (apple-design §1). */
body[x-data='packs'] ul.flex.flex-col.gap-1.mt-3 > li {
  padding: 26px;
  transition: background-color 0.15s, scale 0.15s;
  position: relative;
}
body[x-data='packs'] ul.flex.flex-col.gap-1.mt-3 > li:active {
  scale: 0.98;
  transition-duration: 0ms;
}
@media (hover: hover) {
  body[x-data='packs'] ul.flex.flex-col.gap-1.mt-3 > li:hover div[class='md:text-end'] > div.text-lg.font-bold {
    filter: brightness(1.06);
  }
  body[x-data='packs'] ul.flex.flex-col.gap-1.mt-3 > li.special:hover::before {
    filter: brightness(1.05);
  }
}
body[x-data='packs'] ul.flex.flex-col.gap-1.mt-3 > li::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: linear-gradient(180deg, #ffa24d -27.27%, #fd8c24 127.27%);
  opacity: 0;
  transition: opacity 0.3s ease, filter 0.15s;
  z-index: 0;
}
body[x-data='packs'] ul.flex.flex-col.gap-1.mt-3 > li div.flex.gap-4 > div.flex.flex-col.gap-1 > h3 {
  transition: 0.3s;
  position: relative;
  z-index: 1;
}
body[x-data='packs'] ul.flex.flex-col.gap-1.mt-3 > li div.flex.gap-4 > div.flex.flex-col.gap-1 > span {
  transition: 0.3s;
  position: relative;
  z-index: 1;
}

/* Special pack card: brand-filled (a fill; no rim, no shadow). Its text is
   the dark accent label, rgb(38 40 43): ≥6:1 on the orange, where the old
   white / #eee was 1.7–2.4:1. */
body[x-data='packs'] ul.flex.flex-col.gap-1.mt-3 > li.special::before {
  opacity: 1;
}
body[x-data='packs'] ul.flex.flex-col.gap-1.mt-3 > li.special div.flex.gap-4 > div.flex.flex-col.gap-1 > h3 {
  color: rgb(38 40 43);
}
body[x-data='packs'] ul.flex.flex-col.gap-1.mt-3 > li.special div.flex.gap-4 > div.flex.flex-col.gap-1 > span {
  color: rgb(38 40 43);
}
body[x-data='packs'] ul.flex.flex-col.gap-1.mt-3 > li.special div[class='md:text-end'] > div.text-lg.font-bold {
  background: #151618 !important;
  color: #eeeeee !important;
  position: relative;
  z-index: 1;
}
body[x-data='packs'] ul.flex.flex-col.gap-1.mt-3 > li.special div.relative.text-lg.font-bold > div:nth-of-type(1) {
  color: rgb(38 40 43) !important;
  position: relative;
  z-index: 1;
}
body[x-data='packs'] ul.flex.flex-col.gap-1.mt-3 > li.special div.relative.text-lg.font-bold > p {
  color: #151618 !important;
  position: relative;
  z-index: 1;
}
body[x-data='packs'] ul.flex.flex-col.gap-1.mt-3 > li.special div.flex.gap-4 > .icon {
  background: rgb(255 255 255 / 0.28);
  position: relative;
  z-index: 1;
}

/* Light mode special card */
html[data-mode='light'] body[x-data='packs'] ul.flex.flex-col.gap-1.mt-3 > li.special div[class='md:text-end'] > div.text-lg.font-bold {
  background: #ffffff !important;
  color: #151618 !important;
}

body[x-data='packs'] main div.flex.flex-col.gap-4 {
  margin-bottom: 28px;
}
body[x-data='packs'] div.flex.gap-4 > .icon {
  width: 55px;
  height: 55px;
  display: flex;
  justify-content: center;
  align-items: center;
  /* A filled disc behind the coin, not a 3px ring. */
  background: var(--elev-fill-3);
  border-radius: 999px;
  transition: 0.3s;
}
body[x-data='packs'] div.flex.gap-4 > .icon > img {
  width: 43px;
  height: 43px;
}
body[x-data='packs'] div.flex.gap-4 > div.flex.flex-col.gap-1 > h3 {
  font-size: 22px;
}
/* Secondary text: the AA dimmed token (was #abaeaf, 2.06:1 in light). */
body[x-data='packs'] div.flex.gap-4 > div.flex.flex-col.gap-1 > span {
  color: var(--color-content-dimmed);
  font-size: 13px;
}
body[x-data='packs'] main div.flex.flex-col.gap-4 + div {
  margin-bottom: 20px;
}
body[x-data='packs'] div.relative.text-lg.font-bold {
  display: flex;
  align-items: center;
  gap: 9px;
}
body[x-data='packs'] div.relative.text-lg.font-bold > div:nth-of-type(1) {
  font-size: 14px;
  color: var(--color-content-dimmed);
  font-weight: 500;
  transition: 0.3s;
}
body[x-data='packs'] div.relative.text-lg.font-bold > p {
  font-size: 14px;
  color: var(--elev-tint-text);
  font-weight: 500;
  transition: 0.3s;
}
body[x-data='packs'] div[class='md:text-end'] {
  margin-top: auto;
}
body[x-data='packs'] div[class='md:text-end'] > div.text-lg.font-bold {
  width: 100%;
  padding: 10px 0;
  text-align: center;
  background: linear-gradient(180deg, #ffa24d -27.27%, #fd8c24 127.27%);
  color: #1b1b1b;
  border-radius: 999px;
  font-weight: 800;
  transition: 0.3s;
}
/* (Light mode used #fefefe on the orange price pill: 2.3:1. The dark
   label above serves both modes.) */
body[x-data='packs'] a.absolute.top-0.left-0.w-full.h-full {
  z-index: 2;
  border-radius: inherit;
}
body[x-data='packs'] a.absolute.top-0.left-0.w-full.h-full:focus-visible {
  outline: 2px solid var(--elev-focus-ring);
  outline-offset: 2px;
}

/*
 * Grab-bag of global rules: @property --glow-angle (animated by the quick-access glow in pages/dashboard--qa-*), RTL icon fixes, ApexCharts tweaks, #content height, .remcredit and aside#sidebar width.
 *
 * Moved unchanged from public_html/assets/css/custom-doona.css lines 1–106
 * (asset migration, Phase A). Its position in index.css is part of the
 * cascade; move it only together with a reorder-safety check.
 */
@property --glow-angle {
  syntax: '<angle>';
  initial-value: 0deg;
  inherits: false;
}

/* ============================================
 General / RTL Fixes & Icon Overrides
 ============================================ */

i.text-lg.ti.ti-square-rounded-arrow-left-filled.rtl\:rotate-180 {
transform: none !important;
}
i.text-lg.ti.ti-square-rounded-arrow-left-filled {
transform: scaleX(-1) !important;
}
.flex.items-center.justify-center.w-7.h-7.rounded-\[45\%\].text-white.bg-black.from-black.to-black.bg-linear-to-br {
border-radius: 30px;
}

.max-w-\[140px\].h-6.object-contain.object-left {
transform: scale(1.3);
margin-right: 18px;
}

.flex.items-center.justify-center.w-7.h-7.rounded-\[45\%\].text-white.from-black.to-black.bg-linear-to-br {
color: #f58a06;
}

i.text-2xl.ti.ti-archive-filled {
font-size: 18px;
margin-left: -2px;
}

.apexcharts-tooltip * {
direction: rtl;
}

text.apexcharts-text.apexcharts-xaxis-label.text-xs,
text.apexcharts-text.apexcharts-yaxis-label.text-xs {
direction: rtl;
}

@media (max-width: 768px) {
.gap-2.items-center.justify-center.links {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  overflow-x: visible;
  scrollbar-width: none;
  -ms-overflow-style: none;
}

.flex.gap-2.items-center.justify-center.links>a>svg {
  width: 20px;
  margin-left: 2px;
}

.flex.gap-2.items-center.justify-center.links::-webkit-scrollbar {
  display: none;
}
}

#quick-access+div.flex {
padding-top: 20px;
}

/* [Doona] - Persian UI copy is never justified: in a card-width column it
   opens rivers of space between words (models, packs, billing). The legacy
   utility is kept as a name and now aligns to the start. */
.text-justify {
text-align: start;
}

@media (max-width: 1023px) {
div#content.flex.flex-col.h-screen.overflow-y-auto.w-full {
  height: calc(var(--vh, 1vh) * 92);
}

.sticky.bottom-0.z-40.mt-auto {
  bottom: -3px;
}

.relative>.fixed.z-10.top-4 {
  position: relative;
  margin-right: 60px;
  margin-bottom: 30px;
  margin-left: 0;
}
}

.remcredit {
margin-left: 3px;
padding-block: 5px;
}

.nocredit {
margin-left: 3px;
padding-block: 5px;
background: rgb(245 138 7 / 30%);
font-weight: 500;
border: none;
}

aside#sidebar{
width: calc(var(--spacing)*96) !important;
border-radius: 0 !important;
}


/*
 * History sidebar (aside#sidebar) as an off-canvas drawer below 1024px, its backdrop and open animation; desktop offset of the fixed toolbar under the rose announcement bar.
 *
 * Moved unchanged from public_html/assets/css/custom-doona.css lines 107–187
 * (asset migration, Phase A). Its position in index.css is part of the
 * cascade; move it only together with a reorder-safety check.
 */
/* ============================================
 Sidebar (Mobile)
 ============================================ */

/* [Doona] - Elevation: the history drawer is a side panel over the content
   (DESIGN-ELEVATION.md §2): surface-2, and its edge is the panel's own
   shadow, not a border — the lowest token that reads (shadow-2), per the
   owner's "soft and minimal". aside#sidebar also carries `.sticky`, so without
   this it inherited the nav sidebar's surface-1 glass from
   sidebar--shell.css. The shadow is only cast while the panel is open: closed,
   it sits just past the content's edge and a shadow would leak into view. */
aside#sidebar {
  background: var(--elev-surface-2);
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  box-shadow: none;
}
html[data-sidebar] aside#sidebar,
aside#sidebar[data-key="history"] {
  box-shadow: var(--elev-shadow-2);
}

/* [Doona] - The drawer's close button is a .button-icon (button.css: a
   fill-3 circle, no padding). aside#sidebar also carries .sticky, and the
   nav sidebar's `aside.sticky .button` padding (sidebar--sizing.css) is
   unlayered, so it would squeeze the 32px circle's content box to nothing. */
aside#sidebar .button-icon {
  padding: 0;
}

@media (max-width: 1023px) {
aside#sidebar {
  display: block;
  position: fixed;
  visibility: hidden;
  top: 0;
  left: 0;
  width: 80% !important;
  z-index: 100;
  isolation: isolate;
  transform: translateX(-100%) translateZ(0);
  -webkit-transform: translateX(-100%) translateZ(0);
  transition: transform 0.3s ease, visibility 0.3s;
}

aside#sidebar[data-key="history"] {
  visibility: visible;
  transform: translateX(0) translateZ(0);
  -webkit-transform: translateX(0) translateZ(0);
}

aside#sidebar>div {
  background: var(--elev-surface-2);
  position: relative;
  /* Sidebar content scroll */
  overflow-y: auto;
  max-height: 100vh;
  -webkit-overflow-scrolling: touch;
}
/* Backdrop overlay: the shared scrim, so the drawer dims the page the same
   amount every other sheet does. */
.sidebar-backdrop {
  position: fixed;
  inset: 0;
  background: var(--elev-scrim);
  /* [Doona] - Glass: a scrim dims, it does not blur (and the blur was
     animated from 0 on every open — a full-viewport filter pass per frame). */
  z-index: 99;
  display: none;
}

/* Show backdrop when sidebar is open */
.sidebar-backdrop:has(+ aside#sidebar[data-key="history"]) {
  display: block;
  animation: sidebar-backdrop-in 0.3s ease forwards;
}

@keyframes sidebar-backdrop-in {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

aside#sidebar div.my-8.flex.justify-center{
  margin-bottom: 0;
  padding-bottom: 25px;
}
}

@media (min-width: 1024px) {
.py-3.bg-rose-600~.relative>.fixed.z-10.top-4 {
  padding-top: 60px !important;
}
}


/*
 * Mobile bottom navigation pill (.bottom-nav / .bottom-nav-item), hover/active/tap states, plus the "new" badge styles and their pulse keyframes.
 *
 * Moved unchanged from public_html/assets/css/custom-doona.css lines 188–325
 * (asset migration, Phase A). Its position in index.css is part of the
 * cascade; move it only together with a reorder-safety check.
 */
/* [Doona:START] - Mobile Bottom Navigation - Pill-shaped bar; each item is a two-tone icon with its label under it (gray inactive / tint active) */
.bottom-nav {
backdrop-filter: blur(27px);
-webkit-backdrop-filter: blur(27px);
border-radius: 999px;
width: calc(100% - 24px);
margin: auto auto 14px auto;
}
/* [Doona] - Elevation: a floating material bar — translucent raised surface
   (surface-2 at 78%) + blur, with the menu shadow as its only edge. The 1px
   rims are gone. Dark used to be white/.04 over the page: with the rim gone
   that would have been an invisible bar, so it is the raised surface too
   (lighter than the page, as higher layers are in dark). */
.bottom-nav {
background: color-mix(in srgb, var(--elev-surface-2) 78%, transparent);
border: 0;
box-shadow: var(--elev-shadow-2);
}
@media (prefers-reduced-transparency: reduce) {
.bottom-nav { background: var(--elev-surface-2); }
}
/* [Doona] - Glass: the bar is the regular glass tier now (glass.css); the
   dark imagine/video override (surface-2 at 86% via a background shorthand)
   is gone — it beat the material, wiped its sheen and stayed translucent
   with glass off. */

.bottom-nav-item {
color: var(--color-content-dimmed); /* [Doona] - G5: #9B9B9B was 2.4:1 light */
transition: color 0.18s cubic-bezier(0.4, 0, 0.2, 1), transform 0.12s cubic-bezier(0.4, 0, 0.2, 1);
position: relative;
border-radius: 999px;
padding: 6px 4px;
/* [Doona] - The whole column (icon + label) is the target: at least 48px
   tall, a fifth of the bar wide. */
min-height: 48px;
/* [Doona:START] - Mobile tap responsiveness: kill 300ms delay, disable native tap-highlight, ensure pointer */
touch-action: manipulation;
-webkit-tap-highlight-color: transparent;
-webkit-touch-callout: none;
user-select: none;
cursor: pointer;
/* [Doona:END] */
}

/* Only show hover styles on devices that actually have hover (desktop). On touch devices, the first tap would otherwise trigger a "stuck" hover state and require a second tap to fire the click. */
@media (hover: hover) and (pointer: fine) {
.bottom-nav-item:hover:not(.active) {
color: #6f6f6f;
}
html[data-mode="dark"] .bottom-nav-item:hover:not(.active) {
color: #cfcfcf;
}
.bottom-nav-item:hover:not(.active) i {
transform: scale(1.05);
}
}

/* [Doona] - The active tab is the tint's TEXT colour (--elev-tint-text):
   the raw accent #F58A07 was 2.3:1 behind a 10px label in light. */
.bottom-nav-item.active {
color: var(--elev-tint-text) !important;
}

/* Active item: only color changes – no pill/circle background, matching the new design */
.bottom-nav-item.active > div {
background: transparent;
border-radius: 0;
width: auto;
height: auto;
margin: 0;
box-shadow: none;
border: 0;
}

/* Tabler icon (used by the "more" button when menu is open, and by admin nav) */
.bottom-nav-item.active i {
color: var(--elev-tint-text);
font-size: 20px;
}
.bottom-nav-item i {
transition: transform 0.12s cubic-bezier(0.4, 0, 0.2, 1), color 0.18s cubic-bezier(0.4, 0, 0.2, 1);
font-size: 20px;
}
/* Every icon gets the same 22px box (+ 4px below, misc-nav-gradients.css), so
   all labels share one line: the library cloud is drawn 24×20, and "more"
   swaps its svg for the × glyph when the drawer is open. */
.bottom-nav-item > div > svg.mobile-bar-svgs {
height: 22px;
}
.bottom-nav-item > div > i.ti {
height: 22px;
line-height: 22px;
margin-bottom: 4px;
}

/* Labels under the icons (app and admin nav), like an iOS tab bar. */
.bottom-nav-item span {
transition: color 0.18s cubic-bezier(0.4, 0, 0.2, 1);
font-size: 10px;
font-weight: 500;
line-height: 1.2;
white-space: nowrap;
}
.bottom-nav-item.active span {
color: var(--elev-tint-text);
font-weight: 700;
}

.bottom-nav-item:focus-visible {
outline: 2px solid var(--elev-focus-ring);
outline-offset: -2px;
}

/* Instant tap feedback - no transition on press-down so the user sees immediate response */
.bottom-nav-item:active {
transform: scale(0.92);
transition: transform 0s;
}
/* [Doona:END] */

.nav-new-badge {
position: absolute;
top: -6px;
right: -6px;
background: linear-gradient(135deg, #ff4d6d, #f58a06);
color: #fff;
font-size: 8px;
font-weight: 800;
line-height: 1;
padding: 2.5px 5px;
border-radius: 6px;
z-index: 10;
pointer-events: none;
/* [Doona] - Elevation: no coloured glow; the gradient chip needs no edge. */
box-shadow: none;
animation: badge-pulse 2s ease-in-out infinite;
}

.bottom-nav-item.active .nav-new-badge {
display: none;
}

.nav-new-badge--sidebar {
position: static;
margin-inline-start: -2px;
margin-inline-end: -6px;
font-size: 10px;
padding: 2.5px 5px;
border-radius: 6px;
box-shadow: none;
transform: scale(0.55);
transform-origin: center right;
animation: badge-pulse-sm 2s ease-in-out infinite;
}

@keyframes badge-pulse-sm {
0%, 100% { transform: scale(0.55); opacity: 1; }
50% { transform: scale(0.63); opacity: 0.85; }
}

@keyframes badge-pulse {
0%, 100% { transform: scale(1); opacity: 1; }
50% { transform: scale(1.15); opacity: 0.85; }
}


/*
 * Grab-bag: dark .badge, main padding, library gradient recolour to orange, old quick-links row, chevron mirroring, chat bottom fade, options modal centring (+ imagine options scroll), RTL form arrows, mobile nav menu panel, sidebar tooltip, LTR selects, #quick-access full height.
 *
 * Moved unchanged from public_html/assets/css/custom-doona.css lines 326–443
 * (asset migration, Phase A). Its position in index.css is part of the
 * cascade; move it only together with a reorder-safety check.
 */
/* [Doona] - (dark .badge slab removed: badge.css gives every badge its
   fill-3 / status-tint fill in both modes.) */

#content>.container main.gap-5.pb-20 {
padding-bottom: 0 !important;
}

.to-\[\#006ABF\],
.to-\[\#984CF8\],
.to-\[\#F38383\],
.to-\[\#00A6FB\],
.to-\[\#F77F00\],
.to-\[\#E03339\],
.to-\[\#30C862\],
.to-\[\#27AE60\] {
--tw-gradient-to: #f58a06;
}

.gap-2.items-center.justify-center.links {
flex-direction: row-reverse;
}

.gap-2.items-center.justify-center.links>a {
width: min-content;
}

.gap-2.items-center.justify-center.links>a>svg {
width: 20px;
}
i.ms-auto.text-2xl.ti.ti-chevron-right {
transform: scaleX(-1);
}
.h-8.to-transparent.bg-linear-to-t.from-main {
display: none;
position: fixed;
right: 0;
left: 0;
bottom: 70px;
}
modal-element[name="options"] > form{
top: 50%;
bottom: unset;
transform: translateY(-50%);
}
@media (max-width: 1023px){
  modal-element[name="options"] > form{
      top: unset;
      bottom: 0;
      transform: unset;
  }
}

@media (min-width: 768px) {
body[x-data^="imagine"] modal-element[name="options"]>form {
    max-height: 90%;
    overflow: auto;
}
}
form .relative.p-1.rounded-3xl>.flex.gap-2.items-end {
flex-direction: row-reverse;
}

form .flex.items-center.gap-2 .flex.gap-1.items-center>i {
font-size: 16px;
}

@media (max-width: 426px) {
.gap-2.items-center.justify-center.links>a:nth-child(1) {
    order: 2;
}
.gap-2.items-center.justify-center.links>a:nth-child(2) {
    order: 0;
}
.gap-2.items-center.justify-center.links>a:nth-child(3) {
    order: 1;
}
}
main > div > .grid.gap-1 > .flex > .flex.w-10.bg-linear-to-br{
color: #f58a06;
}
aside.sticky + .sticky.top-0{
height: 64px;
}
main form > .relative.p-1 > input[type="text"].w-full.h-14.p-4{
padding-left: 60px;
}
main form > .relative.p-1 > button[type="submit"].absolute > .ti-arrow-right{
transform: rotateZ(180deg);
}
form div.flex.justify-end > button[type="submit"].button > .ti-arrow-right{
transform: rotateZ(180deg);
}
form div.flex.justify-end > button[type="button"].button.button-outline > .ti-arrow-left{
transform: rotateZ(180deg);
}
nav[x-ref="menu"] div.border-b.border-line-dimmed{
background: var(--color-main);
}
html[data-mode="light"] template[x-ref="sidebarTooltip"] + button.absolute  {
background-color: #cbcbcb;
}
nav[x-ref="menu"] > div.hidden.py-4{
background: var(--color-main);
overflow-y: scroll;
max-height: calc(100vh - 170px);
}
select.mt-2.input.border-line-dimmed.hover\:border-line {
direction: ltr;
}
@media (min-width: 64rem) {
#quick-access {
    height: 100vh !important;
}
}

/*
 * Dashboard page shell: #content positioning, announcement bar overlay, and breaking the quick-access hero out of the container when #quick-access is present.
 *
 * Moved unchanged from public_html/assets/css/custom-doona.css lines 444–489
 * (asset migration, Phase A). Its position in index.css is part of the
 * cascade; move it only together with a reorder-safety check.
 */
body[x-data="dashboard"] div#content{
position: relative;
}
body[x-data="dashboard"] div#content > .py-3.bg-rose-600 {
    position: absolute;
    top: 0;
    right: 0;
    left: 0;
}

body[x-data="dashboard"]:has(#quick-access) div#content {
background: #0f0f0f !important;
overflow: hidden !important;
}

html[data-mode="light"] body[x-data="dashboard"]:has(#quick-access) div#content {
background: #ffffff !important;
}

/* Dashboard: break quick-access out of container constraints (only when #quick-access exists) */
body[x-data="dashboard"]:has(#quick-access) div#content > .container {
max-width: none !important;
padding: 0 !important;
margin: 0 !important;
width: 100% !important;
}

body[x-data="dashboard"]:has(#quick-access) div#content > .container > .max-w-4xl {
max-width: none !important;
padding: 0 !important;
width: 100% !important;
}

body[x-data="dashboard"]:has(#quick-access) div#content > .container > div > main {
padding: 0 !important;
gap: 0 !important;
}

body[x-data="dashboard"]:has(#quick-access) div#content > .relative,
body[x-data="dashboard"]:has(#quick-access) div#content > .container > div > main > div:first-child {
width: 100%;
}

body[x-data="dashboard"]:has(#quick-access) div#content > .container > div {
padding-top: 0 !important;
}

/*
 * Grab-bag: account-menu borders, centred menu-tr, voice avatar/wave (x-wave) and voice-list modal, badge colours, page heading spacing, grid hover scale, outline transitions for .button/.button-accent, quick input padding, avatar icon hiding, markdown images, copy-image hide, button-xs tint, phone-validation colours.
 *
 * Moved unchanged from public_html/assets/css/custom-doona.css lines 490–642
 * (asset migration, Phase A). Its position in index.css is part of the
 * cascade; move it only together with a reorder-safety check.
 */
/* [Doona] - Elevation: the account menu's #242424 / light rim rules were
   removed; the menu is a raised surface with no line (DESIGN-ELEVATION.md). */
div.flex.gap-4.items-center div.menu.menu-tr{
inset-inline-end: auto;
right: 50%;
transform: translateX(50%);
}
/* [Doona] - Bidi (G2): inline `code` direction/isolation is owned by the
   inline style block in layouts/base.twig (ltr + unicode-bidi:isolate).
   The old float:left hack and the direction:inherit override are gone -
   an author `direction` rule here would silently defeat the dir policy. */
div.flex.flex-col.gap-4 > div > h1 + p{
margin-top: 13px;
}
x-wave > button.avatar {
background: #383a42;
}
/* [Doona] - The badge fills that used to sit here (grey slabs by layout
   selector, and a #1eab00 success green at 2.3:1) are gone: .badge and
   .badge-success/-failure/… in badge.css carry the fill and the AA status
   ink. These unlayered rules beat them and painted a red «−۱۲٫۵٪» badge
   grey in dark mode. */
modal-element[name="voice-list-modal"] x-wave + div.grow > div.text-sm{
display: inline-block;
max-width: 10ch;
white-space: nowrap;
}

html[data-mode='light'] x-wave > button.avatar {
  background: #c4c4c4;
}
main.flex.flex-col.gap-5.pb-20.grow > div[class="hidden md:block"]{
  display: block !important;
}
main.flex.flex-col.gap-5.pb-20.grow > div[class="hidden md:block"] > div.flex.gap-3.items-center{
  flex-wrap: wrap;
}
main.flex.flex-col.gap-5 div.grid.grid-cols-2 div.flex-col.gap-6.box {
transition: 0.3s;
}
main.flex.flex-col.gap-5 div.grid.grid-cols-2 div.flex-col.gap-6.box:hover {
  transform: scale(1.02);
}
html[data-mode='light'] main div.grid.grid-cols-2.gap-1 > div.flex a.w-full.button.button-dimmed {
background-color: #333333;
color: #ffffff;
outline-color: #333333;
}
modal-element[name="voice-list-modal"] x-wave div[wave]{
width: 180px;
position: absolute;
right: 63%;
top: 50%;
transform: translateX(-55%) translateY(-50%) scaleY(0.3);
}
@media (max-width: 768px) {
modal-element[name="voice-list-modal"] x-wave div[wave] {
  display: none;
}
modal-element[name="voice-list-modal"] x-wave + div.grow > div.text-sm {
  max-width: unset;
  white-space: unset;
  overflow: unset;
  text-overflow: unset;
  display: unset;
}
}
main.flex.flex-col.gap-5.pb-20 > div > div > div[class="my-10 text-center md:my-0"] > h1.mt-6{
margin-bottom: 18px;
}
main.flex.flex-col.gap-5.pb-20 > div > p.text-content-dimmed{
margin-top: 13px;
}
main.flex.flex-col.gap-5.pb-20 div[class="group/grid"] div.grid.gap-1.grid-cols-2{
gap: 16px;
}
/* [Doona] - Elevation: these set outline-color on every .button (transparent
   at rest, the button colour on hover) and, being unlayered, also hid the
   keyboard focus ring. The hover rim is gone with the no-lines rule;
   button.css owns hover (fill) and :focus-visible (ring). */
.quickInput{
resize: none;
padding-left: 60px;
}
x-avatar[icon="sparkles"] i.ti-sparkles {
display: none;
}
button x-avatar[icon="box"] i.ti-box {
display: none;
}
span.flex.invisible.ms-auto.whitespace-nowrap.badge.group-hover\:visible.shrink-0 {
background: #383a42;
}
html[data-mode='light'] span.flex.invisible.ms-auto.whitespace-nowrap.badge.group-hover\:visible.shrink-0 {
background: #e4e2e2;
}
x-markdown img {
max-width: 298px;
border-radius: 25px;
margin-top: 15px;
}
@media (max-width: 1023px) {
.copyImage {
  display: none !important;
}
}
html[data-mode="light"] .remcredit-.remcredit {
border-color: #eeeeee;
}

button.capitalize.button.button-xs.button-dimmed {
background-color: #f58a0659;
}
.dark\:bg-gray-800:where([data-mode=dark],[data-mode=dark] *) {
background: #111214;
}

/* Phone validation error styles */
.text-red-500 {
color: #ef4444;
}

.border-red-500 {
border-color: #ef4444 !important;
}


/*
 * Desktop sidebar credit button (aside a.button[href=app/billing|app/billing/packs]): glow, sheen, hover/active animation, pulse-glow keyframes.
 *
 * Moved unchanged from public_html/assets/css/custom-doona.css lines 643–768
 * (asset migration, Phase A). Its position in index.css is part of the
 * cascade; move it only together with a reorder-safety check.
 */
/* ============================================
 Credit Button (desktop sidebar)
 ============================================
 [Doona] - Elevation: was an orange OUTLINE (2px rim) with an orange glow and
 an `outline: none !important` that also killed the keyboard focus ring.
 Now a brand-tinted fill with no rim: the tint deepens on hover and again on
 press, the press is instant (scale .98 on pointer-down), and the focus ring
 is back. The 2px border stays, transparent, so the 52px box does not move.
 Text is the content colour on the tint (light ≈ 13:1, dark ≈ 9:1). */
aside a.button[href="app/billing"],
aside a.button[href="app/billing/packs"] {
position: relative;
overflow: hidden;
transition: background-color 0.2s ease, transform 0.12s cubic-bezier(.32, .72, 0, 1);
transform: translateZ(0);
border-radius: 15px;
background: color-mix(in oklab, var(--color-gradient-from, rgb(245 138 6)) 16%, transparent);
border: 2px solid transparent;
color: var(--color-content);
font-weight: 600;
text-shadow: none;
box-shadow: none;
height: 52px;
touch-action: manipulation;
-webkit-tap-highlight-color: transparent;
}

html[data-mode="dark"] aside a.button[href="app/billing"],
html[data-mode="dark"] aside a.button[href="app/billing/packs"] {
background: color-mix(in oklab, var(--color-gradient-from, rgb(245 138 6)) 24%, transparent);
}

aside a.button[href="app/billing"] > img,
aside a.button[href="app/billing/packs"] > img {
transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

aside a.button[href="app/billing"] > x-credit,
aside a.button[href="app/billing/packs"] > x-credit {
position: relative;
z-index: 2;
}

/* A soft light sweep across the fill on hover — inside the shape, so it is
   a material effect, not an edge. */
aside a.button[href="app/billing"]::after,
aside a.button[href="app/billing/packs"]::after {
content: "";
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.18), transparent);
transform: skewX(-15deg);
transition: transform 0.8s ease;
z-index: 1;
pointer-events: none;
}

aside a.button[href="app/billing"]:hover,
aside a.button[href="app/billing/packs"]:hover {
background: color-mix(in oklab, var(--color-gradient-from, rgb(245 138 6)) 22%, transparent);
}
html[data-mode="dark"] aside a.button[href="app/billing"]:hover,
html[data-mode="dark"] aside a.button[href="app/billing/packs"]:hover {
background: color-mix(in oklab, var(--color-gradient-from, rgb(245 138 6)) 30%, transparent);
}

aside a.button[href="app/billing"]:hover > img,
aside a.button[href="app/billing/packs"]:hover > img {
transform: scale(1.1) rotate(5deg);
}

aside a.button[href="app/billing"]:hover::after,
aside a.button[href="app/billing/packs"]:hover::after {
transform: translateX(200%) skewX(-15deg);
}

/* Pointer-down, not click: the press lands instantly. */
aside a.button[href="app/billing"]:active,
aside a.button[href="app/billing/packs"]:active {
background: color-mix(in oklab, var(--color-gradient-from, rgb(245 138 6)) 28%, transparent);
transform: translateZ(0) scale(0.98);
transition: none;
}
html[data-mode="dark"] aside a.button[href="app/billing"]:active,
html[data-mode="dark"] aside a.button[href="app/billing/packs"]:active {
background: color-mix(in oklab, var(--color-gradient-from, rgb(245 138 6)) 36%, transparent);
}

aside a.button[href="app/billing"]:focus-visible,
aside a.button[href="app/billing/packs"]:focus-visible {
outline: 2px solid var(--elev-focus-ring);
outline-offset: 2px;
}

/*
 * Mobile header credit button (a.button-outline.remcredit / .nocredit) animation, mobile-pulse-glow keyframes, and its light-mode variant.
 *
 * Moved unchanged from public_html/assets/css/custom-doona.css lines 769–905
 * (asset migration, Phase A). Its position in index.css is part of the
 * cascade; move it only together with a reorder-safety check.
 */
/* Mobile credit button.
   [Doona] - Elevation: this was an outlined pill (1.5px orange rim) with an
   orange glow, a radial pulse and a sweeping sheen, plus a light variant that
   re-tinted the rim. The look is now one brand-tinted fill with no rim and no
   coloured glow; its colours live with the header in
   layout/mobile-header.css, the only place this button renders.
   What stays here is behaviour: an instant press, a visible focus ring, and a
   hit area that reaches the 44px touch floor past the 40px paint. */
a.button-outline.remcredit[href="app/billing"],
a.button-outline.nocredit[href="app/billing/packs"] {
position: relative;
touch-action: manipulation;
-webkit-tap-highlight-color: transparent;
}

a.button-outline.remcredit[href="app/billing"]::after,
a.button-outline.nocredit[href="app/billing/packs"]::after {
content: "";
position: absolute;
inset: -2px;
}

a.button-outline.remcredit[href="app/billing"] > img,
a.button-outline.nocredit[href="app/billing/packs"] > img {
transition: transform 0.2s cubic-bezier(.32, .72, 0, 1);
}

a.button-outline.remcredit[href="app/billing"]:active > img,
a.button-outline.nocredit[href="app/billing/packs"]:active > img {
transform: scale(1.1) rotate(4deg);
transition: none;
}

a.button-outline.remcredit[href="app/billing"]:focus-visible,
a.button-outline.nocredit[href="app/billing/packs"]:focus-visible {
outline: 2px solid var(--elev-focus-ring);
outline-offset: 2px;
}

/*
 * Light-mode overrides for the desktop credit button and the mobile credit button hover text.
 *
 * Moved unchanged from public_html/assets/css/custom-doona.css lines 906–942
 * (asset migration, Phase A). Its position in index.css is part of the
 * cascade; move it only together with a reorder-safety check.
 */
/* [Doona] - Elevation: the light-mode rim, orange glow, white text-shadow and
   `outline: none !important` overrides that lived here are gone. The credit
   buttons use one tinted-fill recipe in both modes (credit-button.css for the
   sidebar, layout/mobile-header.css for the phone header), and the tokens
   switch with the mode, so there is nothing left to override. */

/*
 * Pin / pinned toggle buttons (button.ti-pin, button.ti-pinned-filled) hover and press animation.
 *
 * Moved unchanged from public_html/assets/css/custom-doona.css lines 943–990
 * (asset migration, Phase A). Its position in index.css is part of the
 * cascade; move it only together with a reorder-safety check.
 */
/* ============================================
 Pin / Pinned Button Animations
 ============================================ */

button.ti.ti-pin.text-base.opacity-0.group-hover\:opacity-100 {
transition: all 0.2s ease;
opacity: 0;
transform: scale(0.9);
}

button.ti.ti-pin.text-base.opacity-0.group-hover\:opacity-100:hover {
color: #f58a06 !important;
transform: scale(1.05);
}

button.ti.ti-pin.text-base.opacity-0.group-hover\:opacity-100:active {
transform: scale(0.95);
}

/* Group hover animation for pin button */
.group:hover button.ti.ti-pin.text-base.opacity-0.group-hover\:opacity-100 {
opacity: 1;
transform: scale(1);
}

/* Pinned Button Animation - Simple & Clean */
button.ti.ti-pinned-filled.text-base.opacity-0.group-hover\:opacity-100 {
transition: all 0.2s ease;
opacity: 0;
transform: scale(0.9);
color: #f58a06 !important;
}

button.ti.ti-pinned-filled.text-base.opacity-0.group-hover\:opacity-100:hover {
color: #f58a06 !important;
transform: scale(1.05);
}

button.ti.ti-pinned-filled.text-base.opacity-0.group-hover\:opacity-100:active {
transform: scale(0.95);
}

/* Group hover animation for pinned button */
.group:hover button.ti.ti-pinned-filled.text-base.opacity-0.group-hover\:opacity-100 {
opacity: 1;
transform: scale(1);
}


/* [Doona] - Nothing hover-only on touch: the pin sits visible where there is
   no hover (a phone), and appears for the keyboard on focus. */
@media (hover: none), (pointer: coarse) {
button.ti.ti-pin.text-base.opacity-0.group-hover\:opacity-100 {
opacity: 1;
transform: none;
}
}

button.ti.ti-pin.text-base.opacity-0.group-hover\:opacity-100:focus-visible {
opacity: 1;
transform: none;
}

/*
 * [x-cloak] hiding, avatar mask sizing, toast offset on mobile, mobile-menu button hide, justified 4-line descriptions.
 *
 * Moved unchanged from public_html/assets/css/custom-doona.css lines 991–1012
 * (asset migration, Phase A). Its position in index.css is part of the
 * cascade; move it only together with a reorder-safety check.
 */
/* Hide elements with x-cloak until Alpine loads */
[x-cloak] {
display: none !important;
}
:is(x-avatar,.avatar)>.mask {
mask-repeat: no-repeat !important;
mask-size: 90% !important;
mask-position: center !important;
}
@media (max-width: 1023px) {
toast-message {
  margin-top: 50px;
}
}
@media (max-width: 1023px) {
button.text-content-dimmed.group-data-\[mobile-menu\=nav\]\/html\:text-content.ms-2,
.doona-mobile-menu-toggle {
  display: none;
}
}
p.text-xs.text-content-dimmed.line-clamp-4 {
text-align: start; /* [Doona] - was justify: rivers between words in the model cards */
}

/*
 * "Light Mode Global Overrides" banner: light colours for dimmed text, buttons, borders, backgrounds; plus a few unrelated global tweaks (badge-success margin, model button tint, tooltip buttons, space-y-4, chat fade margin).
 *
 * Moved unchanged from public_html/assets/css/custom-doona.css lines 1013–1078
 * (asset migration, Phase A). Its position in index.css is part of the
 * cascade; move it only together with a reorder-safety check.
 */
/* ============================================
 Light Mode Global Overrides
 ============================================ */

/* [Doona] - Elevation: was rgb(155 155 155), 2.8:1 on white (fails AA), with a
   :hover that went to rgb(128 128 128) and, being unlayered, beat every
   `hover:text-content` on a dimmed element. Secondary text is now the
   secondary label token: 5.7:1 on white, 5.2:1 on surface-1. */
html[data-mode="light"] .text-content-dimmed {
color: var(--color-content-dimmed);
}

html[data-mode="light"] .button:disabled {
background-color: rgb(219 219 219);
}
/* [Doona] - Elevation: was `.border-line-dimmed { border-color: rgb(227 227
   227) }`, which brought the light-mode rims back over --elev-line. */
html[data-mode="light"] .text-line-dimmed {
color: rgb(209 209 209);
}
.after\:transition-all:after {
margin-left: 2px;
}
html[data-mode="light"] .bg-intermediate {
background: rgb(245 245 245);
}
span.ms-auto.badge.badge-success {
margin-bottom: 10px;
}
main div.grid.grid-cols-2.gap-1 > div.flex a.w-full.button.button-dimmed {
border-radius: 22px;
}
button.button.button-xs.button-outline {
background: #f58a0659;
}
form .flex button.text-base.text-content-dimmed[x-tooltip\.raw] {
margin: 0 5px;
font-size: 18px;
}
form .flex button.text-base.text-content-dimmed.relative[x-tooltip\.raw] {
margin-right: 8px;
}

/* Grouped Options Styles */
.space-y-4 > * + * {
margin-top: 1rem;
}

/* [Doona] - Elevation: was a light-only gradient stop; components.css now
   tints .box-selected in both modes. */

html[data-mode="light"] .text-content-super-dimmed {
color: rgb(168 168 168);
}
html[data-mode="light"] .text-content-super-dimmed:hover {
color: rgb(94 94 94);
}
.h-4.to-transparent.bg-linear-to-t.from-main {
margin-bottom: -10px;
}

/*
 * Video options modal scroll, footer hidden on dashboard / desktop entity pages, and the workspace / user menu (wsmenu / usermenu) open and close transitions.
 *
 * Moved unchanged from public_html/assets/css/custom-doona.css lines 1079–1120
 * (asset migration, Phase A). Its position in index.css is part of the
 * cascade; move it only together with a reorder-safety check.
 */
@media (min-width: 768px) {
body[x-data^="video"] modal-element[name="options"]>form {
    max-height: 90%;
    overflow: auto;
}
}
body[x-data^="dashboard"] footer {
display: none;
}

/* Hide footer on desktop for entity pages (video and imagine with specific content) */
footer.mob-footer {
  transition: opacity 0.3s ease, max-height 0.3s ease, padding 0.3s ease, margin 0.3s ease;
  max-height: 120px;
  overflow: hidden;
}
@media (min-width: 1024px) {
  body[data-entity="true"] footer,
  body[x-data^="packs"] footer {
    opacity: 0;
    max-height: 0;
    padding: 0;
    margin: 0;
  }
}
.menu[x-ref="wsmenu"], .menu[x-ref="usermenu"]{
display: block;
visibility: hidden;
opacity: 0;
transition: 0.3s;
}
.menu[x-ref="wsmenu"]{
transform: translateY(-10px);
}
.menu[x-ref="usermenu"]{
transform: translateY(10px);
}
.menu[x-ref="wsmenu"][data-open], .menu[x-ref="usermenu"][data-open]{
visibility: visible;
opacity: 1;
transform: translateY(0);
}

/*
 * Grab-bag: group/grid button hover (voices list), models page maximize icon and grid gap, nav icon sizing, assistant cards on list() pages.
 *
 * Moved unchanged from public_html/assets/css/custom-doona.css lines 1121–1169
 * (asset migration, Phase A). Its position in index.css is part of the
 * cascade; move it only together with a reorder-safety check.
 */
/* ============================================
 Group Grid Button Hover
 ============================================ */
div[class="group/grid"] .button.button-dimmed {
transition: all 0.3s ease;
}

div[class="group/grid"] .button.button-dimmed:hover {
background-color: var(--color-button-accent) !important;
color: var(--color-button-accent-content) !important;
outline-color: var(--color-button-accent) !important;
}

/* ============================================
 ============================================ */

body[x-data^="models"] i.ti-maximize{
right: unset;
left: 15px;
bottom: 15px;
}
body[x-data^="models"] div[class="group/list"] > div.grid.grid-cols-1{
gap: 12px;
}
i.text-2xl.ti.ti-home,
i.text-2xl.ti.ti-library,
i.text-2xl.ti.ti-cpu {
font-size: 18px;
margin-top: -3px;
}
body[x-data^="list"] a[href="app/chat"]>div {
height: 100%;
}

body[x-data^="list"] a[href="app/chat"]>div>div {
height: 100%;
}

body[x-data^="list"] a[href="app/chat"]>div>div>h3,
body[x-data^="list"] h3[x-text="assistant.name"] {
margin-top: 5px;
margin-bottom: 8px;
}

body[x-data^="list"] div[x-text="assistant.expertise"] {
line-clamp: 3;
-webkit-line-clamp: 3;
line-height: 2;
}

/*
 * Model picker modal (modal-element[name="models"]): z-index on Magic Brush, grid, lock / insufficient-credit states, pin chip, composer form padding, description clamp, models-page modal centring and .price line.
 *
 * Moved unchanged from public_html/assets/css/custom-doona.css lines 1170–1233
 * (asset migration, Phase A). Its position in index.css is part of the
 * cascade; move it only together with a reorder-safety check.
 */
body[x-data^="doonaBrush"] modal-element[name="models"] {
z-index: 150;
}
modal-element[name="models"] div.grid.grid-cols-2.gap-1{
gap: 8px;
}
modal-element[name="models"] div.grid.grid-cols-2.gap-1 .lock-icon{
  border-radius: 32px !important;
}
modal-element[name="models"] .insufficient-credit {
  opacity: 0.65;
  transition: opacity 0.2s ease;
}
modal-element[name="models"] .insufficient-credit:hover {
  opacity: 1;
}
@media (max-width: 500px) {
  modal-element[name="models"] div.grid.grid-cols-2.gap-1{
    grid-template-columns: 1fr;
  }
  modal-element[name="models"] div.grid.grid-cols-2.gap-1 .relative .box{
    gap: 6px;
  }
}
/* [Doona] - (removed) models-page pin repositioning: pins are placed with
   logical `top-4 end-4` in the templates now (G4) - one mechanism. */
modal-element[name="models"] button.ti-pin, modal-element[name="models"] button.ti-pinned-filled {
/* [Doona] - positioning moved to the templates (`top-4 end-4`, G4);
   this rule keeps only the chip look. */
width: fit-content;
background: rgba(0, 0, 0, 0.2);
backdrop-filter: blur(20px);
padding: 5px;
border-radius: 9999px;
}
form div.relative.p-0\.5.rounded-3xl.bg-line-dimmed {
padding: 4px;
border-radius: 27px;
}

form div.flex.gap-2.items-end.p-2.bg-main {
padding-left: 7px;
padding-right: 18px;
}
modal-element[name="models"] p[x-text="m.model.description"],
modal-element[name="models"] p.text-xs.text-content-dimmed.line-clamp-3,
body[x-data^="models"] p[x-text="m.model.description"] {
line-clamp: unset;
-webkit-line-clamp: unset;
}
@media (min-width: 768px) {
body[x-data^="models"] modal-element[name="model"]>div.modal, body[x-data^="models"] modal-element[name="supercharged"]>div.modal {
    top: 50%;
    transform: translateY(-50%);
}
}

body[x-data^="models"] p[x-text="m.model.description"] .price, body[x-data^="models"] p.text-xs.text-content-dimmed.line-clamp-3 .price, body[x-data^="models"] modal-element[name="model"] p[x-text="adapter.model.description"] .price, modal-element[name="models"] p[x-text="m.model.description"], modal-element[name="models"] p.text-xs.text-content-dimmed.line-clamp-3 .price  {
display: block;
margin-top: 10px;
font-size: 13px;
font-weight: 500;
}


/*
 * Model price badge (.price-badge with cheap/moderate/expensive dot) and the price-tier notice banner.
 *
 * Moved unchanged from public_html/assets/css/custom-doona.css lines 1234–1304
 * (asset migration, Phase A). Its position in index.css is part of the
 * cascade; move it only together with a reorder-safety check.
 */
/* Price Badge (separated from description) */
.price-badge {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 11.5px;
  font-weight: 500;
  /* [Doona] - Elevation: was an outlined chip (1px rim, 85% opacity). Now a
     neutral fill-3 chip at full opacity, so the dimmed text keeps 4.9:1. */
  color: var(--color-content-dimmed);
  border: 0;
  background-color: var(--elev-fill-3);
  padding: 2px 6px 2px 7px;
  border-radius: 6px;
}

@media (max-width: 768px) {
  .price-badge {
    margin-inline-start: auto;
  }
}

.price-badge::before {
  content: '';
  display: block;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  margin-top: 1px;
}

.price-badge--cheap::before { background-color: #22c55e; } /* Green */
.price-badge--moderate::before { background-color: #f5da0b; } /* Orange */
.price-badge--expensive::before { background-color: #ef4444; } /* Red */

/* Price tier notice banner */
.price-tier-notice {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  padding: 12px 14px;
  margin-top: 6px;
  margin-bottom: 4px;
  border-radius: 10px;
  font-size: 12px;
  line-height: 1.8;
  color: rgb(var(--content));
  /* [Doona] - Elevation: a blue-tinted banner, no rim. */
  background-color: rgba(59, 130, 246, 0.10);
}

.price-tier-notice > i {
  font-size: 18px;
  flex-shrink: 0;
  margin-top: 1px;
  color: #3b82f6; /* Blue icon */
}

.price-tier-notice .price-badge {
  vertical-align: middle;
  font-size: 10px;
  padding: 1px 6px 1px 7px;
  background-color: var(--elev-fill-3);
}

html[data-mode="light"] .price-tier-notice {
  background-color: rgba(59, 130, 246, 0.08);
}


/*
 * Modal close button (the round ✕ in ~65 modal headers): a Gray icon button.
 *
 * The templates build it from utilities, `w-8 h-8 rounded-full border
 * border-transparent bg-line-dimmed hover:border-line`. Its hover was the
 * border, which the elevation pass made transparent, so the button had no
 * hover or press feedback left. Rather than edit every modal, this one rule
 * matches that pattern (plus the explicit `.close-button` class for new
 * markup) and gives it the Gray icon-button states (DESIGN-ELEVATION):
 * fill-3 at rest, fill-2 on hover, fill-1 + a slight scale while pressed
 * (instant, no transition on press), the focus ring on keyboard focus, and
 * a 44px hit area on touch screens. No border is drawn in any state.
 */
:is(button, a).rounded-full.bg-line-dimmed[class~="hover:border-line"],
.close-button {
  position: relative;
  border-color: transparent;
  background-color: var(--elev-fill-3);
  color: var(--color-content-dimmed);
  transition: background-color 150ms ease, color 150ms ease, transform 150ms ease;
  -webkit-tap-highlight-color: transparent;
}

:is(button, a).rounded-full.bg-line-dimmed[class~="hover:border-line"]:hover,
.close-button:hover {
  border-color: transparent;
  background-color: var(--elev-fill-2);
  color: var(--color-content);
}

:is(button, a).rounded-full.bg-line-dimmed[class~="hover:border-line"]:active,
.close-button:active {
  background-color: var(--elev-fill-1);
  color: var(--color-content);
  transform: scale(0.94);
  transition-duration: 0s;
}

:is(button, a).rounded-full.bg-line-dimmed[class~="hover:border-line"]:focus-visible,
.close-button:focus-visible {
  outline: 2px solid var(--elev-focus-ring);
  outline-offset: 2px;
}

:is(button, a).rounded-full.bg-line-dimmed[class~="hover:border-line"]:disabled,
.close-button:disabled {
  opacity: 0.5;
  transform: none;
}

/* 32px visual, 44px target on touch. */
@media (pointer: coarse) {
  :is(button, a).rounded-full.bg-line-dimmed[class~="hover:border-line"]::after,
  .close-button::after {
    content: '';
    position: absolute;
    inset: -6px;
    border-radius: 9999px;
  }
}

@media (prefers-reduced-motion: reduce) {
  :is(button, a).rounded-full.bg-line-dimmed[class~="hover:border-line"]:active,
  .close-button:active {
    transform: none;
  }
}

/*
 * [Doona] - The shared toggle switch: `input.peer` + `span.rounded-3xl.bg-line`
 * (~150 uses, ~140 of them in admin). It now behaves like the settings
 * switch (`.settings-switch-track`, doona/pages/settings.css), which is the
 * reference: same track, thumb, motion, focus ring and RTL direction.
 *
 * The markup is Tailwind utilities written for LTR (`after:left-0`,
 * `peer-checked:after:left-4`, `after:ms-0.5`), so this module overrides it
 * here, once, instead of in ~150 templates. Everything below is unlayered and
 * beats those utilities.
 */

/* Keyboard: the checkbox was `class="hidden peer"` (display: none), so Tab
 * skipped every switch. Visually hidden instead, still focusable and still
 * announced. Only where it drives a switch track (`:has(~ …)`); a browser
 * without :has() keeps the old display: none. */
input[type='checkbox'].peer.hidden:has(~ span.rounded-3xl.bg-line) {
  display: block;
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
  opacity: 0;
}

/* Off: the strong control fill (fill-1). bg-line sat at ~1.07:1 on the
 * group-filled rows in light mode, so an off switch all but vanished. */
input.peer:not(:checked) ~ span.rounded-3xl.bg-line {
  background-color: var(--elev-fill-1);
}

/* The thumb: logical position, so it starts on the right in RTL and slides
 * to the left when on (iOS mirrors its switches the same way). The LTR
 * utilities put it flush against the left edge with no inset in RTL. */
span.rounded-3xl.bg-line::after {
  left: auto;
  right: auto;
  margin: 0;
  inset-inline-start: 0.125rem;
  box-shadow: var(--elev-shadow-1);
  transition: inset-inline-start 0.15s ease;
}

input.peer:checked ~ span.rounded-3xl.bg-line::after {
  left: auto;
  right: auto;
  inset-inline-start: 1.125rem;
}

/* Focus ring on the track, for keyboard focus only. */
input.peer:focus-visible ~ span.rounded-3xl.bg-line {
  outline: 2px solid var(--elev-focus-ring);
  outline-offset: 2px;
}

/* The state words next to a switch («بله»/«خیر», «فعال»/«غیرفعال») stay on
 * one line. (Their green «on» colour is the AA status ink: text-success
 * resolves to --elev-success-text, elevation.css.) */
label:has(> span.rounded-3xl.bg-line) > span:not(.rounded-3xl) {
  white-space: nowrap;
}

@media (prefers-reduced-motion: reduce) {
  span.rounded-3xl.bg-line,
  span.rounded-3xl.bg-line::after {
    transition: none;
  }
}

/*
 * The user menu in the minimal layout's header (sections/header.twig: 404,
 * policy, install, recovery/reset/signup pages).
 *
 * user-workspace-menus--shell.css positions every `x-ref="usermenu"` for the
 * sidebar account menu: `right: 0; left: -13px; width: 220px`. In this
 * header the trigger sits at the inline end (the left edge in RTL), so that
 * box hung ~130px past the left edge of a phone screen. Open, it was cut
 * off; closed (it stays display:block, only hidden, for the fade) it still
 * widened the page, so phones got a horizontal scroll on every minimal page.
 * Anchor it to the trigger's inline end so it opens into the page.
 */
header div[x-ref="usermenu"] {
  left: auto;
  right: auto;
  inset-inline-end: 0;
}

/*
 * Grab-bag: assistant card text on list() pages, modal scroll-area shadow, voices list on narrow phones, library index avatars, model name clamp in the models modal.
 *
 * Moved unchanged from public_html/assets/css/custom-doona.css lines 1305–1342
 * (asset migration, Phase A). Its position in index.css is part of the
 * cascade; move it only together with a reorder-safety check.
 */
body[x-data^="list"] a[href="app/chat"]>div>div>div.text-sm.text-content-dimmed  {
-webkit-line-clamp: unset;
line-clamp: unset;
line-height: 2;
text-align: center;
}
.modal .scroll-area:after {
bottom: calc(var(--spacing) * -0.3);
}
@media (max-width: 450px) {
body[x-data^='list("voices"'] div[class="group/grid"] div.grid.gap-1.grid-cols-2 {
    grid-template-columns: 1fr;
}
body[x-data^='list("voices"'] div.flex.gap-4.items-center div.flex.flex-wrap.gap-2.items-center{
  display: none;
}
}
body[x-data=""] div.grid.grid-cols-2 > a > .avatar{
  --tw-gradient-from: rgb(245 138 6 / 30%);
  --tw-gradient-to: rgb(245 138 6 / 30%);
  color: #f58a06;
}
body[x-data=""] div.grid.grid-cols-2 > a > .avatar > img{
position: absolute;
bottom: 50%;
right: 50%;
transform: translateX(50%) translateY(50%);
border-radius: 0;
width: 20px !important;
height: 20px !important;
object-fit: contain;
}
modal-element[name="models"] h3[x-text="m.model.name"]{
/* [Doona] - clearance now comes from the header row's `pe-8` (G4) */
line-clamp: 2;
-webkit-line-clamp: 2;
}


/*
 * "Sidebar Sizing & Typography": font sizes, icon scale and logo size inside aside.sticky.
 *
 * Moved unchanged from public_html/assets/css/custom-doona.css lines 1343–1380
 * (asset migration, Phase A). Its position in index.css is part of the
 * cascade; move it only together with a reorder-safety check.
 */
/* ============================================
 Sidebar Sizing & Typography
 ============================================ */

aside.sticky {
gap: 0.875rem;
border-radius: 30px 0 0 30px;
}

aside.sticky i {
font-size: 0.9375rem !important;
transform: scale(0.95);
}

aside.sticky span,
aside.sticky a,
aside.sticky div {
font-size: 0.9375rem !important;
}

aside.sticky i.text-xl {
font-size: 1.125rem !important;
}

aside.sticky i.text-2xl {
font-size: 1.25rem !important;
}

aside.sticky .button {
font-size: 0.9375rem !important;
padding: 0.625rem 0.875rem;
}

aside.sticky img.max-w-\[140px\].h-6 {
max-width: 130px;
height: 1.5rem;
}


/* [Doona] - Home / Library / Models: the quieter row above the tools. */
aside.sticky a.dn-nav-minor,
aside.sticky a.dn-nav-minor div {
font-size: 0.8125rem !important;
}

aside.sticky a.dn-nav-minor {
padding-block: 0.125rem;
color: var(--color-content-dimmed);
}

aside.sticky a.dn-nav-minor:hover {
color: var(--color-content);
}

aside.sticky a.dn-nav-minor.text-content {
color: var(--color-content);
}

/* [Doona] - Tool rows a little shorter (34px, was 42px) so the whole list
   fits a laptop screen without its own scroll. */
aside.sticky nav li > a:not(.dn-nav-minor) {
padding-block: 0.125rem;
}

/*
 * Admin settings small dimmed buttons, and the pre-redesign quick-access link row (#quick-access > .flex > .flex > .links).
 *
 * Moved unchanged from public_html/assets/css/custom-doona.css lines 1381–1410
 * (asset migration, Phase A). Its position in index.css is part of the
 * cascade; move it only together with a reorder-safety check.
 */
body[x-data="settings"] div[x-data="settings"] button.button.button-dimmed.button-xs {
padding: 2px 7px;
box-sizing: content-box;
transition: all 0.3s ease;
}
body[x-data="settings"] div[x-data="settings"] button.button.button-dimmed.button-xs:hover {
background-color: #f58a06 !important;
outline-width: 0;
}

#quick-access > .flex > .flex > .text-content-dimmed.gap-2 {
margin-bottom: 10px;
}
#quick-access > .flex > .flex > .links {
gap: 14px;
}
@media (max-width: 768px) {
#quick-access > .flex > .flex > .links {
  gap: 10px;
}
}
#quick-access > .flex > .flex > .links > a {
padding: 19px;
transition: 0.3s;
}
#quick-access > .flex > .flex > .links > a:hover {
  box-shadow: 0 0 10px black;
  background-color: rgba(255, 255, 255, 0.05);
}


/*
 * "Content Layout & Card Boxes": main grid gaps, global .box look (dark/light), badges, light-mode quick links, apexcharts series brightness, nav spacing, models-modal button LTR, back-link heading spacing, options select arrow.
 *
 * Moved unchanged from public_html/assets/css/custom-doona.css lines 1411–1533
 * (asset migration, Phase A). Its position in index.css is part of the
 * cascade; move it only together with a reorder-safety check.
 */
/* ============================================
 Content Layout & Card Boxes
 ============================================ */

main.flex.flex-col.gap-5.pb-20 > div.flex.flex-col.gap-1 {
gap: 15px;
margin-bottom: 60px;
}
main.flex.flex-col.gap-5.pb-20 > div.flex.flex-col.gap-1 > div.grid.gap-1 {
gap: 15px;
}
main.flex.flex-col.gap-5.pb-20
> div.flex.flex-col.gap-1
> div.grid.gap-1
> .box
.mt-auto
> a {
padding: 0 20px;
}
main.flex.flex-col.gap-5.pb-20 > div > h2 {
font-size: 1.5rem;
}

main.flex.flex-col.gap-5.pb-20 > div > .grid.gap-1.mt-4 {
gap: 15px;
}
main.flex.flex-col.gap-5.pb-20 > div > .grid.gap-1.mt-4 > .box {
transition: 0.3s;
}
main.flex.flex-col.gap-5.pb-20 > div > .grid.gap-1.mt-4 > .box:hover {
  transform: scale(1.02);
}
.box > div > h3 {
margin-bottom: 10px;
}
/* [Doona] - Elevation (DESIGN-ELEVATION.md): a box is the translucent group
   fill with no rim. Was #151618 / #fcfcfc with a #242424 / #d9d9d975 border
   and a `box-shadow: … 0 0 0 0 !important` that blocked every shadow. */
.box {
background-color: var(--elev-group);
border-color: transparent;
border-width: 1px;
border-style: solid;
border-radius: 32px;
}
/* Unlayered, so this file — not components.css — must carry the box states:
   it beats every layered rule, utilities included. */
.box.box-selected {
background-color: color-mix(in oklab, var(--color-gradient-from) 12%, transparent);
}
a.box:hover,
button.box:hover,
.box.cursor-pointer:hover,
.box[class~='hover:border-line']:hover,
.box[class~='hover:border-line-dimmed']:hover {
background-color: var(--elev-group-hover);
}
a.box:active,
button.box:active,
.box.cursor-pointer:active {
background-color: var(--elev-pressed);
}
html[data-mode='light']
main
> div
> .grid.gap-1
> .flex
> .flex.w-10.bg-linear-to-br {
background-color: rgb(245 138 6 / 0%);
}
html[data-mode='light'] #quick-access > .flex > .flex > .links > a {
border-color: transparent;
}
html[data-mode='light'] #quick-access > .flex > .flex > .links > a:hover {
  box-shadow: none;
  background-color: rgba(0, 0, 0, 0.04);
}
html[data-mode='light'] .apexcharts-series path {
filter: brightness(0.5);
}
html[data-mode='dark'] .apexcharts-series path {
filter: brightness(3);
}
nav.flex.overflow-y-auto {
gap: 8px;
padding-top: 10px;
padding-bottom: 10px;
}
modal-element[name='models']
> form
> .grid.grid-cols-2
> div.relative
> button
> div.flex.items-center {
direction: ltr;
}
main
> div
> a.inline-flex.items-center.text-content-dimmed
+ div
> div
> p.text-content-dimmed {
margin-top: 13px;
}
div[class='group/list'] > div.grid.grid-cols-2.gap-1 {
gap: 15px;
}
p {
line-height: 1.7;
}
main > div > a.inline-flex.items-center.text-content-dimmed + h1 {
margin-top: 1rem;
}
main > div + div.grid.grid-cols-2.gap-1 {
gap: 15px;
}
modal-element[name='options'] select {
background-position: right 0.5rem center;
}
html[data-mode='light']
main
div.grid.grid-cols-2.gap-1
> div.flex
> div.mt-auto
> a {
background-color: #333333;
color: #ffffff;
outline-color: #333333;
}
a.inline-flex.items-center.gap-1.text-sm.text-content-dimmed {
transition: 0.1s;
}

/*
 * Billing pages (plans, checkout): states the template utilities cannot
 * reach because the global .box (base/content-layout-boxes.css) is
 * unlayered and beats every Tailwind utility.
 *
 * The current plan is the selected card (.box-selected, the brand-tinted
 * fill). It is still a link to checkout, so it gets the same hover step the
 * other cards get from the .box hover rule — on the tint instead of the
 * group fill, which would wipe the selection out on hover.
 */
@media (hover: hover) {
  .box.box-selected.billing-card:hover {
    background-color: color-mix(in oklab, var(--color-gradient-from) 18%, transparent);
  }
}

/*
 * [Doona:FILE] - Usage logs page (templates/app/usage-logs.twig).
 *
 * Apple-style, no lines (DESIGN-ELEVATION §0): a summary card, type chips,
 * then one inset-grouped card per day. Rows inside a card are separated by
 * the iOS inset hairline (--elev-separator), the one list exception the
 * owner approved; cards, headers and the page carry no line and no shadow.
 *
 * Each kind of usage has one colour (Apple system palette): the row's icon
 * tile, its segment in the summary bar and its legend dot. Light mode uses
 * the darker "accessible" variants so a glyph on its 14% tint stays legible;
 * the bar and the dots carry no text, so they use the bright system colours
 * (--kb), which tell the kinds apart better.
 */

.usage-page {
  --k-chat: #248a3d;
  --k-voice: #0c817b;
  --k-image: #0071e3;
  --k-video: #c93400;
  --k-document: #3634a3;
  --k-code: #0071a4;
  --k-presentation: #b25000;
  --k-speech: #d70015;
  --k-transcription: #7f6545;
  --k-composition: #d30f45;
  --k-enhance: #8944ab;
  --k-neutral: #6c6c70;
  --kb-chat: #34c759;
  --kb-voice: #30b0c7;
  --kb-image: #007aff;
  --kb-video: #ff9500;
  --kb-document: #5856d6;
  --kb-code: #32ade6;
  --kb-presentation: #ffcc00;
  --kb-speech: #ff3b30;
  --kb-transcription: #a2845e;
  --kb-composition: #ff2d55;
  --kb-enhance: #af52de;
  --kb-neutral: #8e8e93;
  --usage-tile-mix: 14%;
  --usage-ease: cubic-bezier(0.32, 0.72, 0, 1);

  display: flex;
  flex-direction: column;
  gap: 1.5rem;
}

/* `mt-6` is only a hook for the legacy pre-loader (see the template). */
.usage-page.mt-6 {
  margin-block-start: 0;
}

:root[data-mode='dark'] .usage-page {
  --k-chat: #30d158;
  --k-voice: #40c8e0;
  --k-image: #0a84ff;
  --k-video: #ff9f0a;
  --k-document: #7d7aff;
  --k-code: #64d2ff;
  --k-presentation: #ffd60a;
  --k-speech: #ff453a;
  --k-transcription: #ac8e68;
  --k-composition: #ff375f;
  --k-enhance: #bf5af2;
  --k-neutral: #98989d;
  --kb-chat: var(--k-chat);
  --kb-voice: var(--k-voice);
  --kb-image: var(--k-image);
  --kb-video: var(--k-video);
  --kb-document: var(--k-document);
  --kb-code: var(--k-code);
  --kb-presentation: var(--k-presentation);
  --kb-speech: var(--k-speech);
  --kb-transcription: var(--k-transcription);
  --kb-composition: var(--k-composition);
  --kb-enhance: var(--k-enhance);
  --kb-neutral: var(--k-neutral);
  --usage-tile-mix: 18%;
}

.usage-page [data-kind] { --k: var(--k-neutral); --kb: var(--kb-neutral); }
.usage-page [data-kind='chat'] { --k: var(--k-chat); --kb: var(--kb-chat); }
.usage-page [data-kind='realtime_voice'] { --k: var(--k-voice); --kb: var(--kb-voice); }
.usage-page [data-kind='image'] { --k: var(--k-image); --kb: var(--kb-image); }
.usage-page [data-kind='video'] { --k: var(--k-video); --kb: var(--kb-video); }
.usage-page [data-kind='document'] { --k: var(--k-document); --kb: var(--kb-document); }
.usage-page [data-kind='code'] { --k: var(--k-code); --kb: var(--kb-code); }
.usage-page [data-kind='presentation'] { --k: var(--k-presentation); --kb: var(--kb-presentation); }
.usage-page [data-kind='speech'] { --k: var(--k-speech); --kb: var(--kb-speech); }
.usage-page [data-kind='transcription'] { --k: var(--k-transcription); --kb: var(--kb-transcription); }
.usage-page [data-kind='composition'] { --k: var(--k-composition); --kb: var(--kb-composition); }
.usage-page [data-kind='enhance-prompt'] { --k: var(--k-enhance); --kb: var(--kb-enhance); }

/* ---------- Filter chips ---------- */

.usage-filters {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-block-end: -0.25rem;
}

.usage-chip {
  position: relative;
  display: inline-flex;
  flex-shrink: 0;
  align-items: center;
  gap: 0.375rem;
  height: 2.25rem;
  padding-inline: 0.875rem;
  border-radius: 999px;
  font-size: 0.875rem;
  font-weight: 500;
  white-space: nowrap;
  transition: background-color 0.15s ease, color 0.15s ease, transform 0.2s var(--usage-ease);
  -webkit-tap-highlight-color: transparent;
}

/* 44px touch target around a 36px chip. */
.usage-chip::before {
  content: '';
  position: absolute;
  inset: -0.25rem 0;
}

.usage-chip > i {
  font-size: 1rem;
}

@media (hover: hover) {
  .usage-chip[aria-pressed='false']:hover {
    background-color: var(--elev-fill-2);
    color: var(--color-content);
  }
}

.usage-chip:active {
  transform: scale(0.97);
  transition: none;
}

.usage-chip[aria-pressed='false']:active {
  background-color: var(--elev-fill-1);
}

/* Phones: one row that scrolls sideways, bleeding to the screen edges,
   instead of three wrapped rows above the content. */
@media (max-width: 767px) {
  .usage-filters {
    flex-wrap: nowrap;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    margin-inline: -1rem;
    padding-inline: 1rem;
    padding-block: 0.25rem;
    margin-block: -0.25rem -0.5rem;
    scrollbar-width: none;
  }

  .usage-filters::-webkit-scrollbar {
    display: none;
  }
}

/* ---------- Summary ---------- */

.usage-summary {
  padding: 1.25rem;
  border-radius: 1.375rem;
  background: var(--elev-group);
}

@media (min-width: 768px) {
  .usage-summary {
    padding: 1.5rem;
  }
}

.usage-summary-label {
  margin: 0;
  font-size: 0.8125rem;
  font-weight: 600;
  line-height: 1.4;
  color: var(--color-content-dimmed);
}

.usage-summary-total {
  display: flex;
  align-items: baseline;
  gap: 0.375rem;
  margin: 0.375rem 0 0;
}

.usage-summary-value {
  font-size: 2.125rem;
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: -0.02em;
  color: var(--color-content);
  font-variant-numeric: tabular-nums;
}

.usage-summary-unit {
  font-size: 1.0625rem;
  font-weight: 500;
  color: var(--color-content-dimmed);
}

.usage-summary-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.375rem;
  margin: 0.375rem 0 0;
  font-size: 0.8125rem;
  line-height: 1.5;
  color: var(--color-content-dimmed);
}

.usage-bar {
  display: flex;
  gap: 2px;
  height: 0.5rem;
  margin-block-start: 1.25rem;
  border-radius: 999px;
  overflow: hidden;
}

.usage-bar-seg {
  flex-basis: 0;
  min-width: 0.25rem;
  background: var(--kb);
}

.usage-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.25rem;
  margin: 0.875rem 0 0;
  padding: 0;
  list-style: none;
  font-size: 0.8125rem;
  line-height: 1.4;
  color: var(--color-content);
}

.usage-legend > li {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
}

.usage-dot {
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 999px;
  background: var(--kb);
}

.usage-legend-amount {
  color: var(--color-content-dimmed);
  font-variant-numeric: tabular-nums;
}

/* ---------- Day sections ---------- */

.usage-day {
  display: flex;
  flex-direction: column;
}

/* The day stays on screen while its rows scroll under it: a solid strip
   of the page colour, no rule and no shadow (the card below has its own
   fill, so the two never merge). */
.usage-day-head {
  position: sticky;
  top: 0;
  z-index: 3;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.5rem 0.5rem 0.625rem;
  background: var(--color-main);
}

/* Private mode paints the page with a fixed glow and dot grid; a solid
   strip would cut a flat band through it, so the day just scrolls. */
html[data-private] .usage-day-head {
  position: static;
  background: none;
}

.usage-day-head > h2 {
  margin: 0;
  font-size: 0.9375rem;
  font-weight: 600;
  line-height: 1.4;
  color: var(--color-content);
}

.usage-day-total {
  font-size: 0.8125rem;
  color: var(--color-content-dimmed);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* ---------- Grouped card + rows ---------- */

.usage-card {
  display: flex;
  flex-direction: column;
  margin: 0;
  padding: 0.25rem;
  list-style: none;
  border-radius: 1.25rem;
  background: var(--elev-group);
}

.usage-item {
  position: relative;
}

.usage-row {
  position: relative;
  display: flex;
  align-items: center;
  gap: 0.75rem;
  min-height: 3.75rem;
  padding: 0.625rem 0.75rem;
  border-radius: 1rem;
  transition: background-color 0.15s ease;
  -webkit-tap-highlight-color: transparent;
}

/* iOS inset separator: starts past the icon tile, stops short of the end. */
.usage-item + .usage-item > .usage-row::before,
.usage-skeleton .usage-row + .usage-row::before {
  content: '';
  position: absolute;
  inset-block-start: 0;
  inset-inline: 3.75rem 0.75rem;
  border-block-start: 1px solid var(--elev-separator);
  pointer-events: none;
  transition: opacity 0.15s ease;
}

.usage-item.is-group > .usage-row {
  user-select: none;
}

.usage-row-toggle {
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

@media (hover: hover) {
  .usage-item.is-link > .usage-row:hover,
  .usage-item.is-group > .usage-row:hover {
    background-color: var(--elev-hover);
  }

  /* A filled row hides the hairlines on both of its edges. */
  .usage-item.is-link:hover > .usage-row::before,
  .usage-item.is-group > .usage-row:hover::before,
  .usage-item.is-link:hover + .usage-item > .usage-row::before {
    opacity: 0;
  }

  /* Its own rule: a browser without :has() drops only this one. */
  .usage-item.is-group:not(.is-open):has(> .usage-row:hover) + .usage-item > .usage-row::before {
    opacity: 0;
  }
}

.usage-item.is-link > .usage-row:active,
.usage-item.is-group > .usage-row:active {
  background-color: var(--elev-pressed);
}

.usage-row-link:focus-visible {
  outline: 2px solid var(--elev-focus-ring);
  outline-offset: -2px;
}

.usage-row-link {
  position: absolute;
  inset: 0;
  z-index: 1;
  border-radius: inherit;
}

.usage-tile {
  display: inline-flex;
  flex-shrink: 0;
  align-items: center;
  justify-content: center;
  width: 2.25rem;
  height: 2.25rem;
  border-radius: 0.625rem;
}

.usage-tile[data-kind] {
  background: var(--elev-fill-3);
  background: color-mix(in oklab, var(--k) var(--usage-tile-mix), transparent);
  color: var(--k);
}

.usage-tile > i {
  font-size: 1.25rem;
}

.usage-main {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: 0.125rem;
  min-width: 0;
}

.usage-skeleton .usage-main {
  gap: 0.5rem;
}

.usage-title-line {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  min-width: 0;
}

.usage-title {
  min-width: 0;
  overflow: hidden;
  font-size: 0.9375rem;
  font-weight: 500;
  line-height: 1.45;
  color: var(--color-content);
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* A chat's title opens the conversation; the rest of its row discloses
   the turns. It sits above the row's toggle so a tap on it never toggles,
   and reaches 44px tall for a finger. The truncating box is the span
   inside, so this hit area is not clipped. */
.usage-title-link {
  position: relative;
  z-index: 2;
  display: flex;
  min-width: 0;
  border-radius: 0.25rem;
}

.usage-title-link::before {
  content: '';
  position: absolute;
  inset-block: -0.6875rem;
  inset-inline: 0;
}

.usage-title-link > .usage-title {
  text-decoration-line: underline;
  text-decoration-color: transparent;
  text-underline-offset: 0.25em;
  transition: text-decoration-color 0.15s ease;
}

.usage-title-link:focus-visible {
  outline-offset: 1px;
}

@media (hover: hover) {
  .usage-title-link:hover > .usage-title {
    text-decoration-color: currentColor;
  }
}

.usage-meta {
  display: flex;
  align-items: baseline;
  gap: 0.3125rem;
  min-width: 0;
  font-size: 0.8125rem;
  line-height: 1.45;
  color: var(--color-content-dimmed);
  white-space: nowrap;
}

.usage-meta-text,
.usage-meta-dot {
  flex-shrink: 0;
}

.usage-meta-model {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}

.usage-amount {
  flex-shrink: 0;
  min-width: 2.5rem;
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--color-content);
  font-variant-numeric: tabular-nums;
  text-align: end;
  white-space: nowrap;
}

.usage-trail {
  display: inline-flex;
  flex-shrink: 0;
  align-items: center;
  justify-content: center;
  width: 1rem;
  color: var(--color-content-dimmed);
}

.usage-trail > i {
  font-size: 1rem;
  transition: transform 0.36s var(--usage-ease);
}

.usage-item.is-open > .usage-row .usage-trail > i {
  transform: rotate(180deg);
}

/* An open chat is one soft surface: its row and its turns together, so the
   turns read as part of it, not as a second card. The hairlines on its
   edges give way to the fill. */
.usage-item.is-group {
  border-radius: 1rem;
  transition: background-color 0.2s ease;
}

.usage-item.is-open {
  background-color: var(--elev-fill-4);
}

.usage-item.is-open > .usage-row::before,
.usage-item.is-open + .usage-item > .usage-row::before {
  opacity: 0;
}

@media (hover: hover) {
  .usage-item.is-open > .usage-row:hover {
    background-color: var(--elev-fill-4);
  }
}

/* ---------- Disclosure: a chat's turns ----------
   The height animates through grid rows (0fr → 1fr), a CSS transition, so
   a second tap mid-way reverses from the current height instead of
   jumping. Closed, the turns are also invisible to focus and AT (the
   visibility flips only after the close has played). */

.usage-disclosure {
  display: grid;
  grid-template-rows: 0fr;
  visibility: hidden;
  transition: grid-template-rows 0.36s var(--usage-ease), visibility 0s linear 0.36s;
}

.usage-item.is-open > .usage-disclosure {
  grid-template-rows: 1fr;
  visibility: visible;
  transition: grid-template-rows 0.36s var(--usage-ease), visibility 0s linear 0s;
}

.usage-disclosure-inner {
  min-height: 0;
  overflow: hidden;
}

.usage-sublist {
  margin: 0 0 0.375rem;
  /* The turns line up with the title column (padding + tile + gap) and the
     credits column of the row above (padding + chevron + gap). */
  margin-inline: 3.75rem 0.75rem;
  padding: 0;
  list-style: none;
  opacity: 0;
  transform: translateY(-0.25rem);
  transition: opacity 0.2s ease, transform 0.36s var(--usage-ease);
}

.usage-item.is-open > .usage-disclosure .usage-sublist {
  opacity: 1;
  transform: none;
}

.usage-subrow {
  position: relative;
  display: flex;
  align-items: center;
  gap: 0.75rem;
  min-height: 2.5rem;
  padding-block: 0.375rem;
  padding-inline: 0;
  font-size: 0.8125rem;
  color: var(--color-content-dimmed);
}

.usage-subrow::before {
  content: '';
  position: absolute;
  inset-block-start: 0;
  inset-inline: 0;
  border-block-start: 1px solid var(--elev-separator);
}

.usage-subrow-time {
  flex-shrink: 0;
  font-variant-numeric: tabular-nums;
}

.usage-subrow-model {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.usage-subrow .usage-amount {
  font-size: 0.8125rem;
  font-weight: 500;
}

/* ---------- Loading, empty, more ---------- */

.usage-skeleton {
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
}

/* The shared .loading fill (line-dimmed) all but vanishes on a group
   card in light mode; a fill step reads in both modes. */
.usage-skeleton .loading {
  background-color: var(--elev-fill-3);
}

.usage-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.5rem;
  padding: 4rem 1rem;
  text-align: center;
}

.usage-empty-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 4rem;
  height: 4rem;
  margin-block-end: 0.5rem;
  border-radius: 999px;
  background: var(--elev-group);
  color: var(--color-content-dimmed);
}

.usage-empty-icon > i {
  font-size: 1.875rem;
}

.usage-empty > h2 {
  margin: 0;
  font-size: 1.0625rem;
  font-weight: 600;
  line-height: 1.4;
  color: var(--color-content);
}

.usage-empty > p {
  max-width: 34ch;
  margin: 0;
  font-size: 0.875rem;
  line-height: 1.7;
  color: var(--color-content-dimmed);
}

.usage-empty > .button {
  margin-block-start: 0.75rem;
}

.usage-more {
  display: flex;
  justify-content: center;
}

@media (prefers-reduced-motion: reduce) {
  .usage-chip,
  .usage-trail > i,
  .usage-disclosure,
  .usage-item.is-open > .usage-disclosure,
  .usage-sublist {
    transition: none;
  }

  .usage-sublist {
    transform: none;
  }
}

/*
 * User menu (x-ref=usermenu) and workspace menu (x-ref=wsmenu) rows, logout colour, borders and hover; a.box hover scale; dark border of the workspace switcher button in the aside.
 *
 * Moved unchanged from public_html/assets/css/custom-doona.css lines 1534–1585
 * (asset migration, Phase A). Its position in index.css is part of the
 * cascade; move it only together with a reorder-safety check.
 */
/* [Doona] - Each of these three also names `li > form > button`, because the
   logout item is a POST form now. The form is display:contents, which removes
   it from LAYOUT but not from SELECTORS: `li > a` never matched the button, so
   logout silently lost its 15px rows, its red, and its hover — while the items
   above it kept all three. Layout invisibility is not selector invisibility. */
div[x-ref='usermenu'] ul > li > a,
div[x-ref='usermenu'] ul > li > form > button {
padding-top: 15px;
padding-bottom: 15px;
transition: 0.2s;
}
div[x-ref='usermenu'] ul > li > a[href='logout'],
div[x-ref='usermenu'] ul > li > form[action='/logout'] > button {
  color: #ff0000;
}
/* [Doona] - OWNER DECISION: the sidebar account menu (usermenu) and the
   workspace menu (wsmenu) keep their PRE-REDESIGN look (as on 353598de4),
   overriding the elevation menu primitive and its separators for these two
   menus only (DESIGN-ELEVATION.md §2.1). Scoped to `aside`: the minimal
   layout's header has a usermenu too, and that one keeps the redesign. The surface, edge and shadow are in
   user-workspace-menus--shell.css; rows, hover and the <hr> rules are here.
   Values are the ones measured on the old build, not approximations.

   Rows: hover was the intermediate fill (dark rgb 25 26 28) on every
   .menu-item, and #ededed on the list rows in light. Press keeps the shared
   pressed fill so a tap still lands instantly. */
aside div[x-ref='usermenu'] .menu-item:hover,
aside div[x-ref='wsmenu'] .menu-item:hover {
background-color: var(--color-intermediate);
}
html[data-mode='light'] aside div[x-ref='usermenu'] ul > li > a:hover,
html[data-mode='light'] aside div[x-ref='usermenu'] ul > li > form > button:hover,
html[data-mode='light'] aside div[x-ref='wsmenu'] > ul > li > a:hover {
background: #ededed;
}
/* Press must out-rank the light list-row hover above (a pressed row is also
   hovered), so it mirrors those selectors and comes after them. */
aside div[x-ref='usermenu'] .menu-item:active,
aside div[x-ref='wsmenu'] .menu-item:active,
html[data-mode] aside div[x-ref='usermenu'] ul > li > a:active,
html[data-mode] aside div[x-ref='usermenu'] ul > li > form > button:active,
html[data-mode] aside div[x-ref='wsmenu'] > ul > li > a:active {
background: var(--elev-pressed);
transition: none;
}

/* Separators: the old full-width 1px rule (no inset, no margin), in the old
   colours — not the inset hairline / gap band other menus use. */
aside div[x-ref='usermenu'] hr,
aside div[x-ref='wsmenu'] hr {
display: block;
height: 0;
margin: 0;
background: none;
border: 0;
border-top: 1px solid rgb(227 227 227);
}
html[data-mode='light'] aside div[x-ref='usermenu'] hr {
border-top-color: rgb(227 228 228 / 53%);
}
html[data-mode='dark'] aside div[x-ref='usermenu'] hr,
html[data-mode='dark'] aside div[x-ref='wsmenu'] hr {
border-top-color: #242424;
}

/* No automatic hairline (and its 9px gap) above logout in this menu. */
aside div[x-ref='usermenu'] li,
aside div[x-ref='wsmenu'] li {
margin-top: 0;
overflow: hidden;
}
aside div[x-ref='usermenu'] li::before,
aside div[x-ref='wsmenu'] li::before {
content: none;
}

a.box {
transition: 0.3s;
}
a.box:hover {
  transform: scale(1.02);
}
html[data-mode='dark']
aside
button.flex.items-center.group.w-full.gap-2.p-2.text-start.border-line {
border-color: transparent;
}
div[x-ref='wsmenu'] > ul > li > a {
padding-top: 15px;
padding-bottom: 15px;
transition: 0.2s;
}


/*
 * Highlighted "default chat bot" card (a.box.box-selected[href="app/chat"]) with rotating glow, hover states and light-mode variant.
 *
 * Moved unchanged from public_html/assets/css/custom-doona.css lines 1586–1761
 * (asset migration, Phase A). Its position in index.css is part of the
 * cascade; move it only together with a reorder-safety check.
 */
/* Default Chat Bot Special Styling */
a.box.box-selected[href="app/chat"] {
position: relative;
background: linear-gradient(135deg, rgba(245, 138, 6, 0.15) 0%, rgba(245, 138, 6, 0.08) 50%, rgba(245, 138, 6, 0.12) 100%);
/* [Doona] - No lines: the orange tint is the selection. The 2px width stays
   (transparent) so the card does not shift. A card is fill only: no shadow,
   no orange glow, no inset highlight. */
border: 2px solid transparent;
box-shadow: none;
transform: translateZ(0);
transition: all 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94);
overflow: hidden;
}

a.box.box-selected[href="app/chat"]::before {
content: "";
position: absolute;
top: -50%;
left: -50%;
width: 200%;
height: 200%;
background: conic-gradient(from 0deg, transparent, rgba(245, 138, 6, 0.1), transparent, rgba(245, 138, 6, 0.1), transparent);
animation: rotate-glow 8s linear infinite;
z-index: 0;
opacity: 0.6;
}

a.box.box-selected[href="app/chat"]::after {
content: "";
position: absolute;
top: 0;
left: -170px;
right: -170px;
bottom: 0;
background: linear-gradient(45deg, transparent 30%, rgba(255, 255, 255, 0.1) 50%, transparent 70%);
transform: translateX(-100%);
transition: transform 1.2s ease;
z-index: 1;
pointer-events: none;
}

a.box.box-selected[href="app/chat"]:hover {
transform: translateZ(0) scale(1.03) translateY(-4px);
box-shadow: none;
background: linear-gradient(135deg, rgba(245, 138, 6, 0.2) 0%, rgba(245, 138, 6, 0.12) 50%, rgba(245, 138, 6, 0.18) 100%);
}

a.box.box-selected[href="app/chat"]:hover::after {
transform: translateX(100%);
}

a.box.box-selected[href="app/chat"]:active {
transform: translateZ(0) scale(0.98) translateY(-2px);
transition: all 0.1s ease;
}

a.box.box-selected[href="app/chat"] > div {
position: relative;
z-index: 2;
}

a.box.box-selected[href="app/chat"] .avatar-lg {
position: relative;
transform: scale(1.1);
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

a.box.box-selected[href="app/chat"]:hover .avatar-lg {
transform: scale(1.15) rotate(5deg);
}

a.box.box-selected[href="app/chat"] h3 {
color: #f58a06;
font-weight: 700;
transition: all 0.3s ease;
}

a.box.box-selected[href="app/chat"]:hover h3 {
transform: scale(1.02);
}

a.box.box-selected[href="app/chat"] .text-content-dimmed {
color: rgba(245, 138, 6, 0.8);
font-weight: 500;
transition: all 0.3s ease;
}

a.box.box-selected[href="app/chat"]:hover .text-content-dimmed {
color: rgba(245, 138, 6, 0.9);
}

@keyframes rotate-glow {
0% {
  transform: rotate(0deg);
}
100% {
  transform: rotate(360deg);
}
}

/* Light mode adjustments for default chat bot - Enhanced */
html[data-mode="light"] a.box.box-selected[href="app/chat"] {
background: linear-gradient(135deg, rgba(245, 138, 6, 0.25) 0%, rgba(245, 138, 6, 0.15) 50%, rgba(245, 138, 6, 0.2) 100%);
backdrop-filter: blur(8px);
-webkit-backdrop-filter: blur(8px);
}

html[data-mode="light"] a.box.box-selected[href="app/chat"]::before {
background: conic-gradient(from 0deg, transparent, rgba(245, 138, 6, 0.15), transparent, rgba(245, 138, 6, 0.15), transparent);
opacity: 0.8;
}

html[data-mode="light"] a.box.box-selected[href="app/chat"]:hover {
background: linear-gradient(135deg, rgba(245, 138, 6, 0.3) 0%, rgba(245, 138, 6, 0.2) 50%, rgba(245, 138, 6, 0.25) 100%);
}

html[data-mode="light"] a.box.box-selected[href="app/chat"] h3 {
color: #b45309;
font-weight: 800;
}

html[data-mode="light"] a.box.box-selected[href="app/chat"]:hover h3 {
color: #92400e;
transform: scale(1.02);
}

html[data-mode="light"] a.box.box-selected[href="app/chat"] .text-content-dimmed {
color: rgba(180, 83, 9, 0.9);
font-weight: 600;
}

html[data-mode="light"] a.box.box-selected[href="app/chat"]:hover .text-content-dimmed {
color: rgba(146, 64, 14, 0.95);
}




/*
 * Force nav icon gradients to orange, LTR price input (admin plan), bottom-nav svg spacing.
 *
 * Moved unchanged from public_html/assets/css/custom-doona.css lines 1762–1778
 * (asset migration, Phase A). Its position in index.css is part of the
 * cascade; move it only together with a reorder-safety check.
 */
/* Override ALL navigation items gradient colors */
nav a > div[style*="--tw-gradient-from"] {
--tw-gradient-from: rgb(245 138 6 / 30%) !important;
--tw-gradient-to: rgb(245 138 6 / 30%) !important;
}

/* Alternative selector for all navigation items */
nav .flex.items-center.gap-2.p-2 > div {
--tw-gradient-from: rgb(245 138 6 / 30%) !important;
--tw-gradient-to: rgb(245 138 6 / 30%) !important;
}
input#price {
direction: ltr;
}
.mobile-bar-svgs {
margin-bottom: 4px;
}

/*
 * Quick-access hero: container, background (radial glow, planet rings), content area, greeting badge with shine/glow, title.
 *
 * Moved unchanged from public_html/assets/css/custom-doona.css lines 1779–2006
 * (asset migration, Phase A). Its position in index.css is part of the
 * cascade; move it only together with a reorder-safety check.
 */
/* ============================================
 Quick Access - Bolt Chat Style
 ============================================ */

/* Container */
#quick-access {
  position: relative !important;
  display: flex !important;
  flex-direction: column !important;
  align-items: center !important;
  justify-content: center !important;
  overflow: hidden !important;
  background: #111214 !important;
  width: 100% !important;
  min-width: 100% !important;
  height: calc(calc(var(--vh, 1vh) * 100) - 4rem);
}

/* --- Background Wrapper --- */
#quick-access .qa-bg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: hidden;
  pointer-events: none;
  user-select: none;
  z-index: 0;
}

@media (max-width: 1023px) {
#quick-access .qa-bg {
  overflow: visible;
  margin-top: -40px;
}
#quick-access .qa-content {
  bottom: 40px;
}
}

/* Radial Blue Glow */
#quick-access .qa-bg-radial {
  position: absolute;
  left: 50%;
  top: 0;
  transform: translateX(-50%);
  width: 4000px;
  height: 1800px;
  background: radial-gradient(
      circle at center 800px,
      rgba(245, 138, 6, 0.8) 0%,
      rgba(245, 138, 6, 0.35) 14%,
      rgba(245, 138, 6, 0.18) 18%,
      rgba(245, 138, 6, 0.08) 22%,
      rgba(17, 17, 20, 0.2) 25%
  );
}

@media (min-width: 640px) {
  #quick-access .qa-bg-radial {
      width: 6000px;
  }
}

/* Planet / Concentric Circles */
#quick-access .qa-bg-planet {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 1600px;
  height: 1600px;
  transform: translate(-50%, 0) rotate(180deg);
}

@media (min-width: 640px) {
  #quick-access .qa-bg-planet {
      width: 3043px;
      height: 2865px;
  }
}

#quick-access .qa-ring {
  position: absolute;
  width: 100%;
  height: 100%;
  border-radius: 50%;
  transform: rotate(180deg);
}

/* --- Content Area --- */
#quick-access .qa-content {
  position: relative;
  z-index: 10;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 20px;
  width: 100%;
  max-width: 800px;
  padding: 0 16px;
}

/* --- Greeting Badge (Announcement Style) --- */
#quick-access .qa-badge {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 20px;
  min-height: 40px;
  border-radius: 9999px;
  font-size: 14px;
  overflow: hidden;
  color: white;
  font-weight: 500;
  cursor: default;
  transition: all 0.3s;
  background: linear-gradient(135deg, rgba(255,255,255,0.1), rgba(255,255,255,0.05));
  backdrop-filter: blur(20px) saturate(140%);
  -webkit-backdrop-filter: blur(20px) saturate(140%);
  /* [Doona] - No lines and no shadow: a chip is its translucent fill. */
  box-shadow: none;
}

#quick-access .qa-badge:hover {
  transform: scale(1.02);
}

#quick-access .qa-badge:active {
  transform: scale(0.98);
}

#quick-access .qa-badge-icon {
  width: 16px;
  height: 16px;
  position: relative;
  z-index: 10;
  color: #f58a06;
  flex-shrink: 0;
}

#quick-access .qa-badge-text {
  position: relative;
  z-index: 10;
  white-space: nowrap;
}

#quick-access .qa-badge-shine {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 50%;
  pointer-events: none;
  opacity: 0.7;
  mix-blend-mode: overlay;
  background: radial-gradient(ellipse at center top, rgba(255, 255, 255, 0.15) 0%, transparent 70%);
}

/* [Doona] - The spinning conic rim was a coloured line around the badge. It
   is painted as nothing now; the keyframes and the light-mode variant stay
   harmless. */
#quick-access .qa-badge-glow {
  display: none;
  position: absolute;
  inset: 0;
  border-radius: inherit;
  padding: 1.5px;
  opacity: 0.55;
  background: conic-gradient(
      from var(--glow-angle),
      transparent 0%,
      transparent 62%,
      rgba(245, 138, 6, 0.4) 76%,
      rgba(255, 107, 26, 0.65) 85%,
      rgba(245, 138, 6, 0.4) 93%,
      transparent 100%
  );
  -webkit-mask:
      linear-gradient(#fff 0 0) content-box,
      linear-gradient(#fff 0 0);
  -webkit-mask-composite: xor;
  mask:
      linear-gradient(#fff 0 0) content-box,
      linear-gradient(#fff 0 0);
  mask-composite: exclude;
  animation: badge-glow-spin 6s linear infinite;
  filter: blur(1.5px);
}

@keyframes badge-glow-spin {
  from { --glow-angle: 0deg; }
  to { --glow-angle: 360deg; }
}

/* --- Title Section --- */
#quick-access .qa-title {
  text-align: center;
  margin-bottom: 4px;
}

#quick-access .qa-title h1 {
  font-size: 2.25rem;
  font-weight: 700;
  color: white;
  letter-spacing: -0.025em;
  margin-bottom: 6px;
  line-height: 1.3;
}

@media (min-width: 640px) {
  #quick-access .qa-title h1 {
      font-size: 3rem;
  }
}

#quick-access .qa-title p {
  font-size: 1rem;
  font-weight: 600;
  color: #ffffff87;
  line-height: 1.6;
}

@media (min-width: 640px) {
  #quick-access .qa-title p {
      font-size: 1.125rem;
  }
}


/*
 * Quick-access chat box: glow border, restored-draft badge, textarea, toolbar, send / attach buttons, file preview.
 *
 * Moved unchanged from public_html/assets/css/custom-doona.css lines 2007–2301
 * (asset migration, Phase A). Its position in index.css is part of the
 * cascade; move it only together with a reorder-safety check.
 */
/* --- Chat Box Container --- */
#quick-access .qa-chatbox-container {
  width: 100%;
  max-width: 700px;
  margin-top: 8px;
}

#quick-access .qa-chatbox-wrapper {
  position: relative;
  width: 100%;
  max-width: 680px;
  margin: 0 auto;
}

/* [Doona] - No lines: the 1px gradient "glow border" peeking out around
   the box is gone (the element stays in the markup, painted as nothing). */
#quick-access .qa-chatbox-glow-border {
  display: none;
}

/* [Doona] - The chat box is a floating surface: surface-2, no ring, no
   outline. Shadows stay minimal (owner): shadow-1 at rest, shadow-2 only on
   focus; in dark mode focus is also the next surface level up (shadows
   barely read on near-black). */
#quick-access .qa-chatbox {
  position: relative;
  border-radius: 16px;
  background: var(--elev-surface-2);
  box-shadow: var(--elev-shadow-1);
  z-index: 1;
  transition: box-shadow 200ms cubic-bezier(.32, .72, 0, 1), background-color 200ms ease;
}

#quick-access .qa-chatbox:focus-within {
  box-shadow: var(--elev-shadow-2);
}

html[data-mode="dark"] #quick-access .qa-chatbox:focus-within {
  background: var(--elev-surface-3);
}

/* [Doona] - Restored-draft badge.
   A flex row at the top of the chatbox holds the pill, which is pushed to
   the END side of the inline axis via `justify-content: flex-end` — that's
   bidi-aware (top-left in RTL, top-right in LTR) and far more reliable
   than auto-margins on a block-level element with `width: max-content`.
   Lives in the normal flow (NOT absolute) so neither RTL nor LTR text in
   the textarea can ever slide under it. Only visible after a left-and-
   came-back restore; the Alpine `draftRestored` flag flips to false on
   the user's first keystroke and the badge fades. */
#quick-access .qa-draft-badge-row {
  display: flex;
  justify-content: flex-end;
  padding: 10px 16px 0;
  pointer-events: none;
}

/* [Doona] - 12px (10px was below the smallest readable size), the brand
   tint pair (--elev-tint-fill / --elev-tint-text: 4.8:1 light, 7:1 dark;
   #fb923c on the light box was 2.3:1), and no blur: it sits on the
   opaque box, there is nothing behind it to frost. */
#quick-access .qa-draft-badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 10px 5px 9px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 600;
  line-height: 1;
  color: var(--elev-tint-text);
  background: var(--elev-tint-fill);
  user-select: none;
  animation: qa-draft-fade-in 240ms ease-out;
}

#quick-access .qa-draft-badge::before {
  content: '';
  width: 6px;
  height: 6px;
  border-radius: 999px;
  background: var(--elev-tint);
  animation: qa-draft-pulse 1.6s ease-in-out infinite;
}

@media (prefers-reduced-motion: reduce) {
  #quick-access .qa-draft-badge,
  #quick-access .qa-draft-badge::before {
    animation: none;
  }
}

@keyframes qa-draft-pulse {
  0%, 100% { opacity: 1;   transform: scale(1); }
  50%      { opacity: 0.45; transform: scale(0.85); }
}

@keyframes qa-draft-fade-in {
  from { opacity: 0; transform: translateY(-2px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* --- Textarea --- */
#quick-access .qa-textarea-wrap {
  position: relative;
}

#quick-access .qa-textarea {
  width: 100% !important;
  resize: none !important;
  background: transparent !important;
  /* [Doona] - 16px: iOS Safari zooms the page into any field under 16px. */
  font-size: 16px !important;
  color: white !important;
  padding: 20px 20px 12px 20px !important;
  border: none !important;
  outline: none !important;
  min-height: 80px;
  max-height: 200px;
  height: 80px;
  display: block;
  box-shadow: none !important;
  border-radius: 16px 16px 0 0 !important;
  /* [Doona] - direction comes from dir="auto" + input.css (G1) */
}

#quick-access .qa-textarea::placeholder {
  /* [Doona] - G5: #5a5a5f was 2.42:1 on the dark box */
  color: var(--color-content-dimmed) !important;
}

#quick-access .qa-textarea:focus {
  outline: none !important;
  box-shadow: none !important;
}

/* --- Toolbar --- */
#quick-access .qa-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 4px 12px 12px;
}

#quick-access .qa-toolbar-start {
  display: flex;
  align-items: center;
  gap: 4px;
}

#quick-access .qa-toolbar-end {
  display: flex;
  align-items: center;
  gap: 8px;
}

/* Keyboard Shortcut */
#quick-access .qa-kbd {
  align-items: center;
  justify-content: center;
  gap: 2px;
  padding: 0 12px;
  font-size: 13px;
  color: var(--color-content-dimmed); /* [Doona] - G5 */
  height: 36px;
  font-weight: 500;
  pointer-events: none;
  border-radius: 8px;
  font-family: inherit;
  border: none;
  background: none;
}

#quick-access .qa-kbd span {
  margin-left: -2px;
}

/* --- Send Button --- */
/* [Doona] - Filled accent button. Fill = the accent token (was a literal
   #f58a06); label = --color-accent-content (css-variables.twig, always AA; white
   on orange was 2.46:1). 40px paint, ::after takes
   the hit area to 44px. Hover only where there is a real pointer; press
   answers on pointer-down. The keyboard ring replaces the old bare
   `outline: none`. */
#quick-access .qa-send-btn {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 40px;
  min-width: 40px;
  padding: 8px 20px;
  border-radius: 9999px;
  font-size: 14px;
  font-weight: 600;
  background: var(--color-accent);
  color: var(--color-accent-content);
  border: none;
  cursor: pointer;
  transition: filter 150ms ease, scale 120ms cubic-bezier(.32, .72, 0, 1);
}

#quick-access .qa-send-btn::after {
  content: "";
  position: absolute;
  inset: -2px;
}

@media (hover: hover) {
  #quick-access .qa-send-btn:hover {
    filter: brightness(1.06);
  }
}

#quick-access .qa-send-btn:active {
  filter: brightness(0.92);
  scale: 0.97;
  transition-duration: 0ms;
}

#quick-access .qa-send-btn:focus-visible,
#quick-access .qa-attach-btn:focus-visible,
#quick-access .qa-file-remove:focus-visible {
  outline: 2px solid var(--elev-focus-ring);
  outline-offset: 2px;
}

#quick-access .qa-send-label {
  white-space: nowrap;
}

/* The arrow follows the label colour (its markup hard-codes stroke="white"). */
#quick-access .qa-send-icon path {
  stroke: currentColor;
}

#quick-access .qa-send-icon {
  width: 20px;
  height: 20px;
  flex-shrink: 0;
  margin-left: -8px;
}

/* --- Attach Image Button --- */
/* [Doona] - Gray icon button: 40px paint (was 32), ::after to the 44px
   touch floor, hover only with a real pointer, keyboard ring above. */
#quick-access .qa-attach-btn {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: var(--elev-fill-3);
  color: var(--color-content-dimmed);
  border: none;
  cursor: pointer;
  transition: background-color 150ms ease, color 150ms ease, scale 120ms cubic-bezier(.32, .72, 0, 1);
  flex-shrink: 0;
}

#quick-access .qa-attach-btn::after {
  content: "";
  position: absolute;
  inset: -2px;
}

@media (hover: hover) {
  #quick-access .qa-attach-btn:hover {
    background: var(--elev-fill-2);
    color: var(--color-content);
  }
}

#quick-access .qa-attach-btn:active {
  background: var(--elev-fill-1);
  scale: 0.97;
  transition-duration: 0ms;
}

/* --- File Preview --- */
#quick-access .qa-file-preview {
  padding: 12px 16px 0;
}

#quick-access .qa-file-thumb {
  position: relative;
  display: inline-block;
  width: 56px;
  height: 56px;
  border-radius: 12px;
  overflow: hidden;
  background: var(--elev-fill-4);
}

#quick-access .qa-file-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

#quick-access .qa-file-remove {
  position: absolute;
  top: 2px;
  right: 2px;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.7);
  color: white;
  border: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  transition: opacity 0.15s;
  padding: 0;
}

/* [Doona] - Never hover-only: with no hover (touch) the remove button is
   always shown, and a keyboard user sees it once it has focus. */
#quick-access .qa-file-thumb:hover .qa-file-remove,
#quick-access .qa-file-remove:focus-visible {
  opacity: 1;
}

@media (hover: none) {
  #quick-access .qa-file-remove {
    opacity: 1;
  }
}

@media (hover: hover) {
  #quick-access .qa-file-remove:hover {
    background: rgba(239, 68, 68, 0.8);
  }
}

/* Light mode adjustments for file upload */
html[data-mode="light"] #quick-access .qa-file-remove {
  background: rgba(0, 0, 0, 0.6);
}


/*
 * Quick-access feature link chips and the fade/slide entry animations.
 *
 * Moved unchanged from public_html/assets/css/custom-doona.css lines 2302–2360
 * (asset migration, Phase A). Its position in index.css is part of the
 * cascade; move it only together with a reorder-safety check.
 */
/* --- Feature Links --- */
#quick-access .qa-links {
  display: flex !important;
  align-items: center;
  justify-content: center;
  gap: 10px;
  flex-wrap: wrap;
  margin-top: 8px;
  flex-direction: row-reverse !important;
}

#quick-access .qa-link-item {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 10px 18px;
  border-radius: 9999px;
  font-size: 13px;
  font-weight: 500;
  /* [Doona] - A filled chip (fill-3 → hover fill-2 → press fill-1), no rim. */
  color: var(--color-content-dimmed);
  background: var(--elev-fill-3);
  transition: all 0.2s;
  text-decoration: none;
  white-space: nowrap;
}

#quick-access .qa-link-item:hover {
  color: var(--color-content);
  background: var(--elev-fill-2);
  transform: translateY(-1px);
}

#quick-access .qa-link-item:active {
  background: var(--elev-fill-1);
  transform: scale(0.98);
}

#quick-access .qa-link-item svg {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
}

/* --- Animations --- */
@keyframes qa-fade-in {
  from { opacity: 0; }
  to { opacity: 1; }
}

@keyframes qa-slide-up {
  from { transform: translateY(8px); opacity: 0; }
  to { transform: translateY(0); opacity: 1; }
}

#quick-access .qa-content {
  animation: qa-fade-in 0.4s ease-out, qa-slide-up 0.4s ease-out;
}


/*
 * Quick-access light-mode overrides.
 *
 * Moved unchanged from public_html/assets/css/custom-doona.css lines 2361–2450
 * (asset migration, Phase A). Its position in index.css is part of the
 * cascade; move it only together with a reorder-safety check.
 */
/* ============================================
 Quick Access - Light Mode Overrides
 ============================================ */

html[data-mode="light"] #quick-access {
  background: #ffffff !important;
}

html[data-mode="light"] #quick-access .qa-bg-radial {
  background: radial-gradient(
      circle at center 800px,
      rgba(245, 138, 6, 0.25) 0%,
      rgba(245, 138, 6, 0.1) 14%,
      rgba(245, 138, 6, 0.05) 18%,
      rgba(245, 138, 6, 0.02) 22%,
      transparent 25%
  );
}

html[data-mode="light"] #quick-access .qa-ring {
  background: #ffffff !important;
  opacity: 0.15;
}

html[data-mode="light"] #quick-access .qa-badge {
  background: linear-gradient(135deg, rgba(255,255,255,0.2), rgba(255,255,255,0.1));
  color: #333;
  box-shadow: none;
}

html[data-mode="light"] #quick-access .qa-badge-icon {
  color: #f58a06;
}

html[data-mode="light"] #quick-access .qa-badge-glow {
  opacity: 0.4;
  background: conic-gradient(
      from var(--glow-angle),
      transparent 0%,
      transparent 65%,
      rgba(245, 138, 6, 0.2) 78%,
      rgba(255, 107, 26, 0.4) 85%,
      rgba(245, 138, 6, 0.2) 92%,
      transparent 100%
  );
}

html[data-mode="light"] #quick-access .qa-title h1 {
  color: #373535;
}

html[data-mode="light"] #quick-access .qa-title p {
  color: var(--color-content-dimmed); /* [Doona] - G5: #888 was 3.54:1 */
}


html[data-mode="light"] #quick-access .qa-textarea {
  color: #1a1a1a !important;
}







/*
 * Quick-access responsive rules (≤768px) and the dashboard body ::before/::after background bands.
 *
 * Moved unchanged from public_html/assets/css/custom-doona.css lines 2451–2524
 * (asset migration, Phase A). Its position in index.css is part of the
 * cascade; move it only together with a reorder-safety check.
 */
/* --- Mobile Responsive --- */
@media (max-width: 768px) {
  #quick-access .qa-title h1 {
      font-size: 1.75rem;
  }

  #quick-access .qa-title p {
      font-size: 0.875rem;
  }

  #quick-access .qa-badge {
      font-size: 13px;
      padding: 6px 16px;
  }

  #quick-access .qa-chatbox-container {
      max-width: 100%;
  }

  #quick-access .qa-chatbox-wrapper {
      max-width: 100%;
  }

  /* [Doona] - Visually hidden, not display:none: the arrow alone shows,
     and the word stays the button's accessible name. */
  #quick-access .qa-send-label {
      position: absolute;
      width: 1px;
      height: 1px;
      overflow: hidden;
      clip-path: inset(50%);
      white-space: nowrap;
  }

  #quick-access .qa-links {
      gap: 8px;
  }

  #quick-access .qa-link-item {
      padding: 8px 14px;
      font-size: 12px;
  }
}

body[x-data="dashboard"]:has(#quick-access)::before {
content: "";
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 200px;
z-index: -1;
}
body[x-data="dashboard"]:has(#quick-access)::after {
content: "";
position: fixed;
bottom: 0;
left: 0;
width: 100%;
height: 200px;
z-index: -1;
}

@media (max-width: 1023px) {
html[data-mode="light"] body[x-data="dashboard"]:has(#quick-access)::before{
  display: none;
}
html[data-mode="light"] body[x-data="dashboard"]:has(#quick-access)::after{
  height: 100px;
  background-color: #faf5ef;
}

html[data-mode="dark"] body[x-data="dashboard"]:has(#quick-access)::before{
  display: none;
}
html[data-mode="dark"] body[x-data="dashboard"]:has(#quick-access)::after{
  height: 100px;
  background-color: #0f0f0f;
}
}


/*
 * Grab-bag: bottom-nav svg stroke/fill colour, legacy imagine result sizing, chat bottom fade on desktop, qa badge emoji offset, desktop modal centring.
 *
 * Moved unchanged from public_html/assets/css/custom-doona.css lines 2525–2569
 * (asset migration, Phase A). Its position in index.css is part of the
 * cascade; move it only together with a reorder-safety check.
 */
@media (max-width: 1023px) {
/* [Doona:START] - Filled icons set fill="currentColor" inline; only override stroke for paths that actually have one (e.g. admin "more" hamburger). Avoid forcing a stroke on filled paths or it adds an outline that visually crops the icon. */
.mobile-bar-svgs path[stroke]{
  stroke: currentColor;
}
.mobile-bar-svgs circle[stroke]{
  stroke: currentColor;
}
.mobile-bar-svgs circle[fill]{
  fill: currentColor;
}
/* [Doona:END] */
}

body[x-data^="imagine"] .object-cover.relative.rounded-\[20px\].w-full,
body[x-data^="imagine"] .relative.rounded-\[20px\].bg-line-dimmed,
body[x-data^="imagine"] .p-1.rounded-3xl.border.group.border-line {
max-height: 500px !important;
width: fit-content;
margin: 0 auto;
}
body[x-data^="imagine"] .p-1.rounded-3xl.border.group.border-line {
max-height: fit-content !important;
}

@media (min-width: 1024px) {
.h-8.to-transparent.bg-linear-to-t.from-main{
  bottom: 0;
}
.h-8.to-transparent.bg-linear-to-t.from-main + .bg-main > .mob-footer{
  background: transparent;
}
}

span.qa-badge-emoji {
margin-top: 5px;
}

@media (min-width: 768px) {
.flex.flex-col.gap-6.modal{
  top: 50%;
  transform: translateY(-50%);
}
}


/*
 * Raychat support banner in the navigation: glow sweep, icon, spinner, online dot, disabled/purchase state, dark mode, hidden on desktop.
 *
 * Moved unchanged from public_html/assets/css/custom-doona.css lines 2570–2805
 * (asset migration, Phase A). Its position in index.css is part of the
 * cascade; move it only together with a reorder-safety check.
 */
/* ============================================
 Raychat Support Banner
 ============================================ */
.support-banner {
position: relative;
display: flex;
align-items: center;
gap: 12px;
width: 100%;
margin-top: auto;
padding: 12px 14px;
border-radius: 14px;
/* [Doona] - Elevation: a brand-tinted fill, no rim and no coloured glow.
   The tint is strong enough to read as a card without one (it was 4%, which
   only the rim made visible). Hover deepens it; press deepens it again,
   instantly. */
border: 0;
background: color-mix(in oklab, var(--color-gradient-from, rgb(245 138 6)) 9%, transparent);
cursor: pointer;
overflow: hidden;
transition: background-color 0.2s ease, transform 0.12s cubic-bezier(.32, .72, 0, 1);
touch-action: manipulation;
-webkit-tap-highlight-color: transparent;
}

.support-banner:hover {
background: color-mix(in oklab, var(--color-gradient-from, rgb(245 138 6)) 14%, transparent);
}

.support-banner:active {
background: color-mix(in oklab, var(--color-gradient-from, rgb(245 138 6)) 19%, transparent);
transform: scale(0.985);
transition: none;
}

.support-banner:focus-visible {
outline: 2px solid var(--elev-focus-ring);
outline-offset: 2px;
}

.support-banner.is-loading {
opacity: 0.7;
pointer-events: none;
}

/* Animated glow sweep */
.support-banner-glow {
position: absolute;
inset: 0;
background: linear-gradient(
  90deg,
  transparent 0%,
  rgba(245, 138, 6, 0.06) 45%,
  rgba(245, 138, 6, 0.03) 55%,
  transparent 100%
);
transform: translateX(-100%);
animation: support-glow-sweep 4s ease-in-out infinite;
pointer-events: none;
}

@keyframes support-glow-sweep {
0%, 100% { transform: translateX(-100%); }
50% { transform: translateX(100%); }
}

/* Icon circle */
.support-banner-icon {
position: relative;
display: flex;
align-items: center;
justify-content: center;
width: 38px;
height: 38px;
border-radius: 50%;
background: linear-gradient(135deg, #f59e0b73, #f58a066b);
color: #fff;
font-size: 18px;
flex-shrink: 0;
box-shadow: none;
}
html[data-mode="light"] .support-banner-icon {
background: linear-gradient(135deg, #f59e0b73, #f58a06eb);
}

/* Loading spinner */
.support-banner-spinner {
width: 20px;
height: 20px;
color: #fff;
animation: support-spin 0.8s linear infinite;
}

@keyframes support-spin {
to { transform: rotate(360deg); }
}

/* Text block */
.support-banner-text {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 2px;
min-width: 0;
}

.support-banner-text strong {
font-size: 13px;
font-weight: 600;
color: var(--color-content);
line-height: 1.3;
}

.support-banner-text small {
font-size: 11px;
color: var(--color-content-dimmed);
line-height: 1.3;
}

/* Online indicator dot */
.support-banner-dot {
margin-inline-start: auto;
flex-shrink: 0;
position: relative;
width: 10px;
height: 10px;
}

.support-banner-dot span {
display: block;
width: 10px;
height: 10px;
border-radius: 50%;
background: #22c55e;
}

.support-banner-dot::before {
content: '';
position: absolute;
inset: -3px;
border-radius: 50%;
background: rgba(34, 197, 94, 0.35);
animation: support-ping 1.5s cubic-bezier(0, 0, 0.2, 1) infinite;
}

@keyframes support-ping {
0% { transform: scale(1); opacity: 0.6; }
75%, 100% { transform: scale(2); opacity: 0; }
}

/* Disabled state (not enough credits): a neutral group fill. */
.support-banner.is-disabled {
background: var(--elev-group);
cursor: default;
text-decoration: none;
}

.support-banner.is-disabled:hover {
background: var(--elev-group-hover);
transform: none;
}

.support-banner-icon.is-locked {
background: linear-gradient(135deg, #9ca3af, #6b7280);
box-shadow: none;
font-size: 16px;
}

.support-banner.is-disabled .support-banner-text strong {
color: var(--color-content-dimmed);
}

.support-banner.is-disabled .support-banner-text small {
color: var(--color-content-dimmed);
}

/* Purchase badge: an orange-tinted chip, no rim. */
.support-banner-badge {
margin-inline-start: auto;
flex-shrink: 0;
padding: 4px 10px;
border-radius: 8px;
font-size: 11px;
font-weight: 600;
color: #B45309;
background: color-mix(in oklab, var(--color-gradient-from, rgb(245 138 6)) 14%, transparent);
transition: background-color 0.2s ease;
white-space: nowrap;
}
html[data-mode="dark"] .support-banner-badge { color: #fbbf24; }

.support-banner.is-disabled:hover .support-banner-badge {
background: color-mix(in oklab, var(--color-gradient-from, rgb(245 138 6)) 22%, transparent);
}

/* Hide on desktop */
@media (min-width: 1024px) {
.support-banner {
  display: none;
}
}

/*
 * "Misc Utilities" banner: quick-access send icon nudge and Turbo progress bar colour.
 *
 * Moved unchanged from public_html/assets/css/custom-doona.css lines 2806–2819
 * (asset migration, Phase A). Its position in index.css is part of the
 * cascade; move it only together with a reorder-safety check.
 */
/* ============================================
 Misc Utilities
 ============================================ */

svg.qa-send-icon {
position: relative;
top: -1px;
right: -2px;
}

.turbo-progress-bar {
background: #f58a06 !important;
}


/*
 * Chat composer surfaces (start of the "Free Message Badge" banner): inner/wrapper backgrounds, reasoning settings button tiers, input bar, placeholder colour, model picker pill.
 *
 * Moved unchanged from public_html/assets/css/custom-doona.css lines 2820–2897
 * (asset migration, Phase A). Its position in index.css is part of the
 * cascade; move it only together with a reorder-safety check.
 */
/* ============================================
 Free Message Badge
 ============================================ */

/* [Doona] - No-lines redesign: the composer is ONE floating surface. The
   wrapper (quote + inner + input bar) carries surface-2 and a soft shadow;
   the parts inside it are transparent, so they read as one material with no
   seam. At rest it is a filled field (fill-4) with the lightest shadow;
   while typing it lifts to the raised surface with shadow-2 (white in light
   mode, one level lighter in dark). Shadows stay minimal (owner): a white
   box on a white page with only shadow-1 all but vanished, so the fill is
   what keeps it visible at rest. */
.doona-chat-wrapper {
  background: var(--elev-fill-4);
  box-shadow: var(--elev-shadow-1);
  transition: box-shadow 200ms cubic-bezier(.32, .72, 0, 1), background-color 200ms ease;
}

.doona-chat-wrapper:focus-within {
  background: var(--elev-surface-2);
  box-shadow: var(--elev-shadow-2);
}

html[data-mode="dark"] .doona-chat-wrapper:focus-within {
  background: var(--elev-surface-3);
}

.doona-chat-inner {
  background-color: transparent;
}

.doona-settings-btn {
  background-color: var(--elev-fill-3);
  border-radius: 15px;
  padding: 3px 10px;
  height: 28px;
  font-weight: 300;
  transition: background-color 150ms ease;
}

.doona-settings-btn:hover {
  background-color: var(--elev-fill-2);
}

.doona-settings-btn:active {
  background-color: var(--elev-fill-1);
}

.doona-settings-btn.dr-tier-off,
.doona-settings-btn.dr-tier-none {
  color: var(--color-content-dimmed); /* [Doona] - G5 */
}

.doona-settings-btn:not(.dr-tier-off):not(.dr-tier-none) {
  background: color-mix(in oklab, currentColor 16%, transparent);
}

.doona-settings-btn:not(.dr-tier-off):not(.dr-tier-none):hover {
  background: color-mix(in oklab, currentColor 22%, transparent);
}

.doona-chat-inner textarea::placeholder {
  /* [Doona] - G5: was rgba(155,155,155,.4/.5) = 1.51:1 composited (failed in
     BOTH themes). The token is theme-aware: 5.04:1 light / 6.97:1 dark. */
  color: var(--color-content-dimmed);
}


.doona-chat-input-bar {
  background-color: transparent;
  color: var(--color-content-dimmed); /* [Doona] - G5 */
  border-radius: 15px;
}

/* When there's no file-attach (+) button, add a small right padding so text doesn't stick to the edge */
.doona-chat-input-bar.pl-4 div.grow:has(> .autogrow-textarea),
.doona-chat-input-bar.pl-4 .autogrow-textarea,
.doona-chat-input-bar.pl-4 .autogrow-textarea > textarea {
  padding-right: 3px;
}

/* [Doona] - The model picker is a Tinted button (.button-tinted: the brand
   tint at ~15% with tint-coloured text, AA in both modes) in light and dark
   alike. It was Filled orange in light (white on #f89c3e, 2.05:1) and
   tinted only in dark, through an inline colour and !important. Same class
   in the studios (doona-imagine.twig, doona-video.twig). Only the pill's
   shape lives here; the colours come from the button style's tokens. */
.doona-model-picker {
  height: 28px;
  padding-inline: 8px;
  border-radius: 15px;
  font-weight: 500;
  font-feature-settings: "ss02" off !important;
}

/* Phones: the chips stay 28px tall but answer a 44px tap (8px above and
   below; 4px to the sides, half the row's gap, so neighbours never
   overlap). */
@media (pointer: coarse) {
  .doona-model-picker,
  .doona-settings-btn {
    position: relative;
  }

  .doona-model-picker::after,
  .doona-settings-btn::after {
    content: "";
    position: absolute;
    inset: -8px -4px;
  }
}



/* [Doona:FILE] - The activity row of a chat message (thinking and tool
   steps, snippets/cards/message.twig). Closed, it is a plain line; open, the
   header and its steps share one soft surface, so the steps read as the
   inside of the row and not as loose lines under it. The row is pulled out
   by its own padding, so its text stays on the message's text column in
   both states. */

.dn-activity {
  margin-inline: -0.75rem;
  border-radius: 0.875rem;
  transition: background-color 0.2s ease;
}

.dn-activity.is-open {
  background-color: var(--elev-fill-4);
}

.dn-activity__head {
  min-height: 2.25rem;
  padding: 0.375rem 0.75rem;
  border-radius: 0.875rem;
}

@media (hover: hover) {
  .dn-activity:not(.is-open) > .dn-activity__head:hover {
    background-color: var(--elev-hover);
  }
}

.dn-activity:not(.is-open) > .dn-activity__head:active {
  background-color: var(--elev-pressed);
}

.dn-activity__body {
  padding-inline: 0.75rem;
}

.dn-activity.is-open .dn-activity__body {
  padding-block: 0.25rem 0.75rem;
}

.dn-activity__done {
  color: var(--color-content-dimmed);
}

/* [Doona] The clear (×) button every search box gets while it holds text
   (resources/assets/js/base/search-clear.js). Same look as the history
   drawer's own: a small grey disc, a 44px hit area. */
.dn-search-clear {
  position: absolute;
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 1.375rem;
  height: 1.375rem;
  padding: 0;
  border: 0;
  border-radius: 9999px;
  background: var(--elev-fill-3, rgb(120 120 128 / 0.16));
  color: var(--color-content-dimmed);
  transform: translateY(-50%);
  cursor: pointer;
  transition: background-color 0.15s ease, color 0.15s ease, transform 0.1s ease;

  &[hidden] {
    display: none;
  }

  & .ti {
    font-size: 0.8125rem;
  }

  &::after {
    content: "";
    position: absolute;
    inset: -0.6875rem;
  }

  @media (hover: hover) {
    &:hover {
      background: var(--elev-fill-2, rgb(120 120 128 / 0.24));
      color: var(--color-content);
    }
  }

  &:active {
    background: var(--elev-fill-1, rgb(120 120 128 / 0.32));
    transform: translateY(-50%) scale(0.92);
  }

  &:focus-visible {
    outline: 2px solid var(--elev-focus-ring);
    outline-offset: 2px;
  }
}

/* Room for the × so typed text never runs under it. */
input.dn-search-clearable {
  padding-inline-end: 2.25rem !important;
}

/* The browser's own clear control would sit beside ours. */
input.dn-search-clearable::-webkit-search-cancel-button {
  -webkit-appearance: none;
  display: none;
}

/*
 * Free-quota panels: shared header band (icon, title) and the quiet/loud action button.
 *
 * Moved unchanged from public_html/assets/css/custom-doona.css lines 2898–2997
 * (asset migration, Phase A). Its position in index.css is part of the
 * cascade; move it only together with a reorder-safety check.
 */
/* [Doona:START] - Header / body / action, shared by both quota panels.
   The popover and the exhausted panel are one component in two states, so
   they get one structure: an icon-marked title band, the rows, then a single
   action. Previously each had its own header and its own button, which is why
   they never looked related. */
.doona-quota-head {
  display: flex;
  align-items: center;
  gap: 9px;
  /* [Doona] - Elevation: no hairline under the title. The panel's 16px band
     gap and the title's weight and icon seat it above the rows. */
  padding-bottom: 2px;
}

/* The same gift mark the billing card uses for this feature. An icon that
   changes meaning between screens is worse than no icon. */
.doona-quota-head__icon {
  display: grid;
  place-items: center;
  flex: none;
  width: 26px;
  height: 26px;
  border-radius: 9px;
  font-size: 14px;
  background: rgba(52, 211, 153, 0.14);
  color: #34d399;
}
html[data-mode="light"] .doona-quota-head__icon { background: rgba(22, 101, 52, 0.10); color: #166534; }
/* Spent is amber, not red: running out of a free allowance is expected, not
   an error. */
.doona-quota-head__icon--spent { background: rgba(245, 158, 11, 0.15); color: #fbbf24; }
html[data-mode="light"] .doona-quota-head__icon--spent { background: rgba(180, 83, 9, 0.10); color: #b45309; }

.doona-quota-head__title {
  font-size: 12.5px;
  font-weight: 650;
  letter-spacing: 0.006em;
  color: #f1f5f9;
  min-width: 0;
}
html[data-mode="light"] .doona-quota-head__title { color: #0f172a; }

/* One button, two volumes. Quiet while the user still has messages — this is
   navigation. Loud only in the state where they have run out and the action
   matters more than the numbers above it. */
.doona-quota-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  width: 100%;
  /* 44px is the touch floor and this is the only tappable thing in the panel. */
  min-height: 44px;
  padding: 0 14px;
  /* [Doona] - Elevation: a gray (fill-3) button, no rim: hover fill-2, press
     fill-1 (instant), focus ring. */
  border: 0;
  border-radius: 12px;
  font-size: 12.5px;
  font-weight: 650;
  letter-spacing: 0.006em;
  color: var(--color-content);
  background: var(--elev-fill-3);
  text-decoration: none;
  cursor: pointer;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
  transition: background 140ms ease, transform 120ms cubic-bezier(.32, .72, 0, 1);
}
.doona-quota-btn i { font-size: 15px; }
.doona-quota-btn:hover { background: var(--elev-fill-2); color: var(--color-content); text-decoration: none; }
/* Pointer-down, not click. */
.doona-quota-btn:active { background: var(--elev-fill-1); transform: scale(0.985); transition: none; }
.doona-quota-btn:focus-visible { outline: 2px solid var(--elev-focus-ring); outline-offset: 3px; }

.doona-quota-btn--loud {
  color: #0b1220;
  background: #f59e0b;
}
.doona-quota-btn--loud:hover { color: #0b1220; background: #fbbf24; }
.doona-quota-btn--loud:active { background: #d97706; }

@media (prefers-reduced-motion: reduce) {
  .doona-quota-btn { transition: background 140ms ease; }
  .doona-quota-btn:active { transform: none; }
}
/* [Doona:END] */


/*
 * Free-quota meters: auto-fit rows, label/value, track and fill, note, "unlimited" row.
 *
 * Moved unchanged from public_html/assets/css/custom-doona.css lines 2998–3128
 * (asset migration, Phase A). Its position in index.css is part of the
 * cascade; move it only together with a reorder-safety check.
 */
/* [Doona:START] - The meters, shared by both quota panels.
   Two rows side by side when there is room for two, one column when there is
   not — and `auto-fit` is what decides, not a viewport media query.

   That distinction is the whole bug this replaced. The breakpoint asked how
   wide the WINDOW was; what actually constrains these rows is how wide their
   own container is. In the composer the panel is a flex item beside the model
   picker, so on a phone the window was 490px (media query silent, two columns
   kept) while the container was 150px — and "بی‌نهایت" spilled out past the
   panel's edge, because the value is `white-space: nowrap` and nothing was
   clipping it.

   `minmax(150px, 1fr)` states the requirement in the terms that matter: a
   column is worth having at 150px and not below. The grid then answers for
   itself at any width, in any container, without a second place to keep in
   sync. */
.doona-quota-meters {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 14px 16px;
}

/* [Doona] - One row: head, gauge, caption, in that order.

   This briefly held the gauge's slot open with a fixed grid track, so that a
   row with no gauge — the unlimited one — kept its caption level with the
   caption of the row beside it. That was the right fix while the meters sat
   side by side. They no longer do: both panels are now capped narrower than
   two columns need, so the meters always stack, there is no neighbour to line
   up with, and the reserved slot was simply a hole between the unlimited
   marker and its caption. Back to a plain stack. */
.doona-quota-row {
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 0;
}

.doona-quota-row__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  min-width: 0;
}

.doona-quota-row__label {
  font-size: 11.5px;
  /* Small text wants a touch of positive tracking; the value beside it is
     larger and gets negative. One value for both is wrong for one of them. */
  letter-spacing: 0.012em;
  color: #a8b6c8;
  white-space: nowrap;
}
html[data-mode="light"] .doona-quota-row__label { color: #55636f; }

.doona-quota-row__value {
  font-size: 13px;
  /* Emphasis by weight, not size — the row has no room to spare. */
  font-weight: 650;
  letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums;
  color: #f1f5f9;
  white-space: nowrap;
}
html[data-mode="light"] .doona-quota-row__value { color: #0f172a; }

.doona-quota-track {
  height: 5px;
  border-radius: 999px;
  /* At 0/10 the track is all there is; any lighter and it read as a stray
     horizontal rule rather than an empty gauge. */
  /* [Doona] - The track is fill-1 (the slider-track fill), with no inset rim. */
  background: var(--elev-fill-1);
  overflow: hidden;
}

.doona-quota-track__fill {
  height: 100%;
  border-radius: 999px;
  background: #f59e0b;
  /* Width is data, so it moves only far enough to read as a change — and not
     at all for anyone who asked for less motion. */
  transition: width 280ms cubic-bezier(.32, .72, 0, 1);
}
@media (prefers-reduced-motion: reduce) {
  .doona-quota-track__fill { transition: none; }
}

.doona-quota-row__note {
  font-size: 11px;
  /* Vibrancy: over a translucent surface, flat grey at 400 dissolves into
     whatever shows through it. */
  font-weight: 450;
  letter-spacing: 0.014em;
  color: #a3b0c0;
}
html[data-mode="light"] .doona-quota-row__note { color: #4b5866; }

/* "Unlimited" is a statement, not a measurement — so this row has no gauge,
   and the glyph sits beside the word rather than instead of it, surviving a
   font that lacks the icon and reading the same to a screen reader. */
.doona-quota-infinite {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  color: #16a34a;
}
html[data-mode="light"] .doona-quota-infinite { color: #166534; }
.doona-quota-infinite i { font-size: 14px; }
/* The head aligns its label and value on the baseline, which is right for a
   number. This one is an inline-flex box with an icon in it, so the baseline
   it offers is synthesised and sits low: it made its own head 1.5px taller
   than the other row's, and the grid slot below inherited the offset, so the
   two captions no longer started on the same line. It is a mark, not a
   measurement — centre it and leave the baseline to the numbers. Measured:
   both heads 19.5px, both captions on one line.

   Scoped to the meter head, because that measurement was taken there. The
   billing card uses this same marker in a baseline row of its own, but its
   two meters are separate stacked blocks with no shared line to fall out of,
   so it has nothing to gain from the change and should not inherit it
   unmeasured. */
.doona-quota-row__head .doona-quota-infinite { align-self: center; }
/* Inside the glass the darker green measured 2.32:1 against bright
   bleed-through; this holds 6:1 there and 9:1 over the plain page. The
   billing card keeps the darker one — it sits on a solid surface. */
.doona-quota-pop__panel .doona-quota-infinite { color: #34d399; }
/* [Doona:END] */


/*
 * Free-quota disclosure popover: trigger pill, caret, glass panel, phone layout, Alpine enter/leave classes (dq-*), reduced-motion / transparency / contrast variants.
 *
 * Moved unchanged from public_html/assets/css/custom-doona.css lines 3129–3333
 * (asset migration, Phase A). Its position in index.css is part of the
 * cascade; move it only together with a reorder-safety check.
 */
/* [Doona:START] - Quota disclosure, built as a material.
   ---------------------------------------------------------------------------
   The first version was an opaque slab that cross-faded in. Three things were
   wrong with that, and they are the three the platform actually notices:

   1. It faded from nowhere. A popover that appears detached from the control
      that opened it breaks the spatial relationship — you cannot tell what
      produced it. It now scales from the pill's own corner, so the trigger and
      the panel are visibly the same object at two sizes, and it leaves along
      the identical path (mirrored curve) rather than dissolving in place.
   2. It was a painted rectangle, not a surface. Chrome that floats over
      content should read as translucent material with the content visible
      through it; that is what tells you it is temporary and above, rather
      than part of the page.
   3. Its press feedback waited for the click. `:active` fires on pointer-down,
      which is where the acknowledgement belongs — the commit still happens on
      release.

   No spring library is used and none is wanted: this is a discrete open/close
   with no gesture behind it, so there is no velocity to inherit and nothing to
   grab mid-flight. What it should be is critically damped — reaching the
   target without overshoot — and cubic-bezier(.32,.72,0,1) is that curve.
   Bounce here would be motion for its own sake. */

.doona-quota-pop { position: relative; display: inline-flex; }

.doona-free-msg--button {
  border: 0;
  cursor: pointer;
  font: inherit;
  font-size: 12px;
  font-weight: 300;
  gap: 5px;
  position: relative;
  /* Removes the ~300ms tap delay: the press must land now, not eventually. */
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
  transition: transform 120ms cubic-bezier(.32, .72, 0, 1);
}
/* The pill is 28px tall for density, under the 44px touch floor. Rather than
   inflate the composer, the hit area is extended past the paint. */
.doona-free-msg--button::after {
  content: "";
  position: absolute;
  inset: -8px;
}
/* Pointer-DOWN, not click. */
.doona-free-msg--button:active { transform: scale(0.96); }
.doona-free-msg--button:focus-visible {
  outline: 2px solid var(--elev-focus-ring);
  outline-offset: 3px;
}

.doona-free-msg__caret {
  font-size: 11px;
  opacity: 0.75;
  transition: transform 240ms cubic-bezier(.32, .72, 0, 1);
}
.doona-free-msg__caret.is-open { transform: rotate(180deg); }

.doona-quota-pop__panel {
  position: absolute;
  bottom: calc(100% + 10px);
  inset-inline-start: 0;
  z-index: 40;
  display: flex;
  flex-direction: column;
  /* Header, body and action are three bands; they need more separation from
     each other than the rows inside the body need from one another, or the
     panel reads as one undifferentiated list. */
  gap: 16px;
  /* 280, not 260: at 260 both Persian meter labels wrapped while sitting side
     by side. What keeps them from wrapping now is the meters' own 150px
     minimum column, which stacks them rather than squeezing them. */
  width: max(280px, 100%);
  padding: 15px 16px;
  border-radius: 18px;

  /* A material, not a fill. The blur is what makes it read as a layer above
     the page; saturation keeps what shows through from going grey. */
  /* 0.85, not 0.72. Measured against the worst case rather than the average
     one: this panel opens over the transcript, so what shows through can be
     bright text, and at 0.72 the captions fell to 3.46:1 and the unlimited
     green to 2.32:1 against that. Still visibly a material — the backdrop
     still reads through it — but the surface, not the page, is what carries
     the text now. Legibility is not the thing to spend for a nicer blur. */
  /* [Doona] - Elevation: the raised surface (surface-2) as the material, so
     in dark it is lighter than the page under it, as higher layers are.
     It was rgba(22,26,33), darker than the surfaces around it. */
  background: color-mix(in srgb, var(--elev-surface-2) 88%, transparent);
  -webkit-backdrop-filter: blur(24px) saturate(180%);
  backdrop-filter: blur(24px) saturate(180%);
  /* [Doona] - Elevation: the bright "glass edge" (a 1px border with a
     brighter top) was a line round the panel. The edge is now the shadow
     alone — one soft popover shadow, not a stack. */
  border: 0;
  box-shadow: var(--elev-shadow-2);
  font-feature-settings: "ss02" on;

  /* Anchored to the trigger. In RTL the panel's start edge is its right edge,
     which is the corner the pill sits under. */
  transform-origin: bottom left;
}
[dir="rtl"] .doona-quota-pop__panel { transform-origin: bottom right; }

/* Some browsers have no backdrop-filter. A 0.72-alpha surface over arbitrary
   content is illegible without the blur, so those get an opaque one. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .doona-quota-pop__panel { background: var(--elev-surface-2); }
}

/* 18px, not 14, for the gap the popover actually uses. Narrow enough and the
   two meters stack; at 14 the first one's caption then sat hard against the
   second one's label and five lines read as one block rather than two things.
   The column count is auto-fit's business either way — this only spaces them. */
.doona-quota-pop__panel .doona-quota-meters { gap: 18px; }



/* On a phone the panel is wider than the room to the side of its trigger.
   Measured: at a 393px viewport the 320px panel hung 53px past the composer's
   left edge, and at 430px it still hung 16px past — the pill sits second in
   the chip row, so anchoring to it leaves less than a panel's width of screen.

   So below 480px it stops hanging off the pill and spans the composer instead:
   the chip row becomes the containing block and the panel takes its full
   width. It cannot then be clipped by an edge it is aligned to.

   A viewport query rather than a container one, and deliberately: what is
   being avoided here is the SCREEN edge, which is the viewport's business. On
   a phone the composer is the content width anyway, so the two agree. */
@media (max-width: 480px) {
  .doona-composer-chips { position: relative; }
  .doona-quota-pop { position: static; }
  .doona-quota-pop__panel {
    inset-inline: 0;
    width: auto;
    /* Both insets pin it to the start edge, and the cap keeps it from growing
       into a band across the composer — same width as the exhausted panel, so
       the two states are the same size of thing. */
    max-width: 300px;
    /* Spanning the composer, it no longer grows out of one corner. */
    transform-origin: bottom center;
  }
  [dir="rtl"] .doona-quota-pop__panel { transform-origin: bottom center; }
}

/* Materialise, don't fade. Scale, offset and blur arrive together so the panel
   reads as a surface forming — a plain opacity ramp reads as an image being
   turned up. */
/* [Doona] - Glass: the blur is no longer part of the entrance. Animating
   backdrop-filter re-rasterises the blur every frame (DESIGN-ELEVATION.md
   «Glass»: never animate it); scale + offset + opacity carry the arrival. */
.dq-enter { transition: opacity 300ms cubic-bezier(.32, .72, 0, 1), transform 300ms cubic-bezier(.32, .72, 0, 1); }
.dq-enter-start { opacity: 0; transform: scale(.92) translateY(8px); }
.dq-enter-end { opacity: 1; transform: scale(1) translateY(0); }

/* The same path, reversed — inverse control points, and shorter, because an
   exit that takes as long as an entrance feels reluctant. */
.dq-leave { transition: opacity 200ms cubic-bezier(1, 0, .68, .28), transform 200ms cubic-bezier(1, 0, .68, .28); }
.dq-leave-start { opacity: 1; transform: scale(1) translateY(0); }
.dq-leave-end { opacity: 0; transform: scale(.94) translateY(6px); }

/* Reduced motion is not "no feedback" — it is the same information without
   the vestibular part. The panel still appears; it just does not travel. */
@media (prefers-reduced-motion: reduce) {
  .doona-free-msg--button,
  .doona-free-msg__caret { transition: none; }
  .dq-enter { transition: opacity 160ms ease; }
  .dq-leave { transition: opacity 120ms ease; }
  .dq-enter-start, .dq-leave-end { transform: none; }
}

/* Asked for less transparency: frost it solid rather than thinning the blur,
   which would leave the worst of both. */
@media (prefers-reduced-transparency: reduce) {
  .doona-quota-pop__panel {
    background: var(--elev-surface-2);
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }
}

/* Asked for more contrast: solid, with a boundary that is unmistakably a
   boundary. This is the one place an edge line is wanted (DESIGN-ELEVATION
   §1.4: --elev-line becomes visible under prefers-contrast: more). */
@media (prefers-contrast: more) {
  .doona-quota-pop__panel {
    background: var(--elev-surface-2);
    border: 1px solid #8b96a5;
  }
  html[data-mode="light"] .doona-quota-pop__panel {
    border-color: #47525f;
  }
}
/* [Doona:END] */


/*
 * Free-quota exhausted panel (doona-quota-out, foot, note) and the green "N free messages" pill (.doona-free-msg), with a ≤360px size.
 *
 * Moved unchanged from public_html/assets/css/custom-doona.css lines 3334–3418
 * (asset migration, Phase A). Its position in index.css is part of the
 * cascade; move it only together with a reorder-safety check.
 */
/* [Doona:START] - Free-quota exhausted state.
   Sits where the green "N پیام رایگان" pill was: at zero the pill used to just
   disappear, leaving the user with no explanation at the one moment they need
   one. Deliberately calm rather than alarming — running out of a free
   allowance is expected, not an error — so it borrows the surface treatment of
   the existing pill and not the failure palette.
   Contrast checked against both themes; the meter never carries meaning by
   colour alone, the numbers beside it say the same thing. */
.doona-quota-out {
  display: flex;
  flex-direction: column;
  gap: 10px;
  width: 100%;
  /* 300, not 420. At 420 the panel matched the composer on a phone, and three
     full-width rectangles stacked — panel, button, input — read as a slab
     rather than as a note about the composer. Capped here it is a card sitting
     at the start edge, which is also what keeps the meters stacked. */
  max-width: 300px;
  padding: 12px 14px;
  border-radius: 16px;
  /* [Doona] - Elevation: a group-filled card, no rim. */
  background: var(--elev-group);
  font-feature-settings: "ss02" on;
}

/* The panel's last band when the user still has credit: the sentence that
   says what happens next, then a quiet way to check the balance. One wrapper
   because the two live inside a single x-if, and it keeps its own spacing
   rather than inheriting the panel's wider band gap. */
.doona-quota-out__foot {
  display: flex;
  flex-direction: column;
  gap: 8px;
  /* Without separation this sentence sat directly under the meters'
     captions in the same size and colour, and read as a third caption rather
     than as the panel's conclusion. [Doona] - Elevation: it used a hairline;
     now it is space (the panel gap plus this padding) and the note's own
     colour step below. */
  padding-top: 8px;
}

.doona-quota-note {
  margin: 0;
  font-size: 11.5px;
  line-height: 1.65;
  letter-spacing: 0.012em;
  color: var(--color-content);
  opacity: 0.86;
}


/* [Doona:END] */

.doona-free-msg {
  display: inline-flex;
  align-items: center;
  width: fit-content;
  gap: 6px;
  font-size: 12px;
  font-weight: 300;
  color: #22c55e;
  background: #21c55e17;
  border-radius: 15px;
  padding: 0 8px;
  height: 28px;
  font-feature-settings: "ss02" on;
}

html[data-mode="light"] .doona-free-msg {
  color: #16a34a;
}

/* [Doona:START] - Shrink free-message badge on very small screens (<=360px) */
@media (max-width: 360px) {
  .doona-free-msg {
    font-size: 10px;
  }
}
/* [Doona:END] */


/*
 * Turn off Persian digits (font-feature ss02) in the options/models modals, di-* model buttons and model selector buttons; keep them in prices and the free-message badge.
 *
 * Moved unchanged from public_html/assets/css/custom-doona.css lines 3419–3455
 * (asset migration, Phase A). Its position in index.css is part of the
 * cascade; move it only together with a reorder-safety check.
 */
/* Disable Persian numerals in options/models modals and model button */
modal-element[name="options"],
modal-element[name="options"] *,
modal-element[name="models"],
modal-element[name="models"] *,
button.di-model-btn,
button.di-dropdown-item.di-dropdown-item-sm,
span.di-preview-meta-item,
button.di-chip.di-chip-active,
span.dv-cinema-label {
font-feature-settings: "ss02" off !important;
}
/* Keep Persian numerals in model price and free message badge */
modal-element[name="models"] .model-price,
modal-element[name="models"] .model-price *,
modal-element[name="models"] .doona-free-msg,
modal-element[name="models"] .doona-free-msg * {
font-feature-settings: "ss02" on !important;
}

/* Disable Persian numerals in model selector button */
button.button.button-xs.button-outline {
font-feature-settings: "ss02" off !important;
}

button.button.button-xs.button-outline * {
font-feature-settings: "ss02" off !important;
}

/* Disable Persian numerals in dimmed model selector button */
button.button.button-xs.button-dimmed {
font-feature-settings: "ss02" off !important;
}

button.button.button-xs.button-dimmed * {
font-feature-settings: "ss02" off !important;
}

/*
 * Grab-bag: chat message list bottom margin by viewport height, admin/app switcher buttons, hide the Ministral model card, quick-access links ≤430px, long-prompt wrapping in the chat composer, nav list gap on short screens.
 *
 * Moved unchanged from public_html/assets/css/custom-doona.css lines 3456–3542
 * (asset migration, Phase A). Its position in index.css is part of the
 * cascade; move it only together with a reorder-safety check.
 */
@media (min-width: 1024px) and (min-height: 800px) {
  .flex.flex-col.gap-4 > .flex.flex-col.gap-6.mt-6 { margin-bottom: 30px; }
}
@media (max-width: 1023px) and (max-height: 800px) {
  .flex.flex-col.gap-4 > .flex.flex-col.gap-6.mt-6 { margin-bottom: -20px; }
}
@media (max-width: 1023px) and (min-height: 800px) {
  .flex.flex-col.gap-4 > .flex.flex-col.gap-6.mt-6 { margin-bottom: -3vh; }
}
@media (max-width: 1023px) and (min-height: 1000px) {
  .flex.flex-col.gap-4 > .flex.flex-col.gap-6.mt-6 { margin-bottom: -4vh; }
}
@media (max-width: 1023px) and (min-height: 1200px) {
  .flex.flex-col.gap-4 > .flex.flex-col.gap-6.mt-6 { margin-bottom: -5vh; }
}

/* Admin <-> App switcher buttons in navbar */
.btn-switch-to-app,
.btn-switch-to-admin {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  /* [Doona] - No lines: the violet tint alone marks the switcher. */
  background: linear-gradient(135deg, rgba(139, 92, 246, 0.16) 0%, rgba(109, 40, 217, 0.16) 100%);
  color: rgb(167, 139, 250);
  cursor: pointer;
  transition: all 0.2s ease;
  text-decoration: none;
  flex-shrink: 0;
}

.btn-switch-to-app:hover,
.btn-switch-to-admin:hover {
  background: linear-gradient(135deg, rgba(139, 92, 246, 0.26) 0%, rgba(109, 40, 217, 0.26) 100%);
  transform: scale(1.08);
  color: rgb(167, 139, 250);
}
/* Hide Ministral model specifically */
div.relative.flex.group:has(h3[title="Ministral"]) {
  display: none !important;
}

@media (max-width: 430px) {
  #quick-access .qa-link-item {
      padding: 8px 11px;
      font-size: 11px;
  }
  #quick-access .qa-link-item > img{
      margin-left: 1px;
      width: 16px;
      height: 16px;
  }
}

/* Keep long unbroken prompt text inside the chat composer. */
.sticky.bottom-0.z-40.mt-auto form div.grow:has(> .autogrow-textarea),
.sticky.bottom-0.z-40.mt-auto form .autogrow-textarea,
.sticky.bottom-0.z-40.mt-auto form .autogrow-textarea > textarea {
  min-width: 0;
}

.sticky.bottom-0.z-40.mt-auto form .autogrow-textarea::after,
.sticky.bottom-0.z-40.mt-auto form .autogrow-textarea > textarea {
  overflow-wrap: anywhere;
  word-break: break-word;
}

.sticky.bottom-0.z-40.mt-auto form div.ms-auto:has(> .button.button-accent),
.sticky.bottom-0.z-40.mt-auto form div.ms-auto:has(> a.button.button-dimmed) {
  flex-shrink: 0;
}

/* [Doona] - (removed) the old 'Reasoning blocks: force LTR' rules matched
   x-markdown[x-effect*=".reasoning"], a selector nothing renders anymore
   (thinking parts bind $el.setContent(part.content)); they also forced
   direction:ltr on every descendant, which would override the G1 dir
   policy on any future match. Verified dead before removal. */
@media (max-height: 880px) {
  nav.flex.overflow-y-auto ul.flex.flex-col {
      gap: 7px !important;
  }
}

/*
 * Voice pricing notice banner (responsive, light mode).
 *
 * Moved from public_html/assets/css/custom-doona.css lines 3543–3582 (asset
 * migration, Phase A); the rim was later dropped for the elevation design.
 * Its position in index.css is part of the cascade; move it only together
 * with a reorder-safety check.
 */
/* Voice Pricing Notice */
.voice-pricing-notice {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 16px;
  border-radius: 12px;
  font-size: 13px;
  line-height: 1.8;
  color: rgb(var(--content));
  /* Elevation: a tinted fill carries the notice; no rim. */
  background-color: rgba(245, 138, 6, 0.1);
}

@media (max-width: 768px) {
  .voice-pricing-notice {
    font-size: 11.5px;
    gap: 6px;
    padding: 8px 12px;
    line-height: 1.5;
  }
}

.voice-pricing-notice > i {
  font-size: 20px;
  flex-shrink: 0;
  color: #f58a06;
}

@media (max-width: 768px) {
  .voice-pricing-notice > i {
    font-size: 16px;
  }
}

html[data-mode="light"] .voice-pricing-notice {
  background-color: rgba(245, 138, 6, 0.09);
}


/*
 * Grab-bag of page-scoped tweaks: voiceover composer row, voice details modal, chat message list overflow, audio player label, admin dashboard stat boxes, account page row, transcriber composer and segments.
 *
 * Moved unchanged from public_html/assets/css/custom-doona.css lines 3583–3639
 * (asset migration, Phase A). Its position in index.css is part of the
 * cascade; move it only together with a reorder-safety check.
 */
body[x-data^="voiceover"] form .relative.p-1.rounded-3xl>.flex.gap-2.items-end{
  flex-direction: row;
}
@media (min-width: 767px) {
  modal-element[name="voice-details-modal"] .gap-8.modal{
      height: 600px;
      top: unset;
      bottom: 50%;
      overflow-y: scroll;
      transform: translateY(50%);
  }
}
/* [Doona] - The chat thread: wide content is cut sideways, but with
   clip, not hidden. overflow-x: hidden turns overflow-y into auto, so the
   thread became a second scroller inside #content (a 4px overflow was
   enough), and opening a long reasoning block showed two scrollbars.
   Older engines without clip keep hidden. */
.flex.flex-col.gap-4 > .flex.flex-col.gap-6.mt-6 {
  overflow-x: hidden;
  overflow-x: clip;
}
.flex.gap-4.items-center.p-2.box.bg-main .grow .absolute.px-2.bg-main.text-xs.text-content-dimmed {
  min-width: 200px;
}

/* Admin dashboard stat boxes: prevent overflow on narrow grid cells */
section[x-data="stats"] .grid.grid-cols-2 > .box.bg-line-super-dimmed {
  min-width: 0;
  overflow: hidden;
}

section[x-data="stats"] .grid.grid-cols-2 > .box.bg-line-super-dimmed .flex.gap-2.items-center {
  flex-wrap: wrap;
  min-width: 0;
}

section[x-data="stats"] .grid.grid-cols-2 > .box.bg-line-super-dimmed x-credit.text-2xl {
  min-width: 0;
  word-break: break-all;
}

@media (max-width: 767px) {
  section[x-data="stats"] .grid.grid-cols-2 > .box.bg-line-super-dimmed x-credit.text-2xl {
    font-size: 1.25rem;
  }
}
body[x-data^="account"] .flex.flex-col.gap-6.box > div > .flex.justify-between.items-center.p-3 .inline-flex.gap-2.items-center{
  flex-direction: row-reverse;
}
body[x-data^="transcriber"] form .relative.p-1.rounded-3xl>.flex.gap-2.items-end{
  flex-direction: row;
}

/* Transcriber segment items padding - specific to transcriber page segments */
body[x-data^="transcriber"] .flex.flex-col.gap-4.mt-4 > .flex.gap-4.items-start.group {
  padding-bottom: 15px !important;
}
@media (max-width: 1023px) {
  .flex.flex-col.gap-4 > .flex.flex-col.gap-6.mt-6 > div:last-of-type {
      padding-bottom: 30px;
  }
}


/*
 * User chat message bubble (div.message[data-role=user]): content bubble, edit form, dark mode, hidden avatar/name; plus hiding the "open in full size" link on mobile.
 *
 * Moved unchanged from public_html/assets/css/custom-doona.css lines 3640–3694
 * (asset migration, Phase A). Its position in index.css is part of the
 * cascade; move it only together with a reorder-safety check.
 */
/* User Chat Message Bubble
   NOTE: v4.0.0 introduces extra wrapper levels (parts->group wrapper) between the
   avatar column and .content, so these selectors use descendant (space) combinators
   instead of direct-child (>) to match both old fallback and new parts-based DOM. */
div.message[data-role="user"] > div.flex.flex-col.gap-2.min-w-0.grow div.content,
div.message[data-role="user"] > div.flex.flex-col.gap-2.min-w-0.grow > form {
  background-color: #f3f4f6;
  padding: 0.75rem 1.25rem;
  border-radius: 1.5rem;
  border-start-start-radius: 0.25rem;
  width: fit-content;
  max-width: 100%;
  overflow-wrap: anywhere;
}

div.message[data-role="user"] > div.flex.flex-col.gap-2.min-w-0.grow > form {
  width: 100%;
}

div.message[data-role="user"] > div.flex.flex-col.gap-2.min-w-0.grow > form textarea {
  color: inherit;
}

div.message[data-role="user"] > div.flex.flex-col.gap-2.min-w-0.grow > form > .flex.gap-2.items-center.mt-5 {
  margin-top: 1rem;
}

div.message[data-role="user"] > div.flex.flex-col.gap-2.min-w-0.grow {
  flex-grow: 0 !important;
}

html[data-mode="dark"] div.message[data-role="user"] > div.flex.flex-col.gap-2.min-w-0.grow div.content,
html[data-mode="dark"] div.message[data-role="user"] > div.flex.flex-col.gap-2.min-w-0.grow > form {
  background-color: #27272a;
}

html[data-mode="dark"] div.message[data-role="user"] > div.flex.flex-col.gap-2.min-w-0.grow > form textarea {
  color: #f3f4f6;
}

div.message[data-role="user"] > div.sticky.top-2 {
  margin-top: 0;
}

div.message[data-role="user"] > div.flex.flex-col.gap-2.min-w-0.grow > div.font-bold {
  padding-top: 0.35rem;
}

/* Hide "Open in full size" button on mobile */
@media (max-width: 768px) {
  a[x-tooltip\.raw="باز کردن در اندازه کامل"] {
    display: none !important;
  }
}


/*
 * KaTeX math in chat messages / x-markdown: display blocks, LTR inline math.
 *
 * Moved unchanged from public_html/assets/css/custom-doona.css lines 3695–3725
 * (asset migration, Phase A). Its position in index.css is part of the
 * cascade; move it only together with a reorder-safety check.
 */
/* ============================================
   KaTeX / Math Formula Styling
   ============================================ */

.message .content .katex-display,
x-markdown .katex-display {
  margin: 1rem 0;
  padding: 0.5rem 0;
  overflow-x: auto;
  overflow-y: hidden;
  direction: ltr;
  text-align: center;
}

.message .content .katex,
x-markdown .katex {
  direction: ltr;
}

.message .content p > .katex,
x-markdown p > .katex {
  display: inline-block;
  vertical-align: middle;
}

/* [Doona] - (removed) the per-element text-align:start list for chat
   messages. text-align:start inherits from .message .content (set in
   layouts/base.twig) and resolves against each block's own dir attribute,
   so an LTR code-explanation paragraph left-aligns while Persian blocks
   right-align - one inherited declaration instead of a selector list. */


/*
 * Grab-bag: Latin digits for adapter model name, back-link chevron order, account head row width, warning icon chip colour, modal scroll-area shadow, .bidi-chevron RTL mirroring.
 *
 * Moved unchanged from public_html/assets/css/custom-doona.css lines 3726–3752
 * (asset migration, Phase A). Its position in index.css is part of the
 * cascade; move it only together with a reorder-safety check.
 */
p[x-text*="adapter.model.name"] {
  font-feature-settings: "ss02" off !important;
}
a.font-semibold.text-xs.flex.items-center:has(> i.ti-chevron-right),
a.font-semibold.text-xs.text-content-dimmed.hover\:text-content.inline-flex.items-center:has(> i.ti-chevron-right) {
  flex-direction: row-reverse;
}
.flex.flex-col.items-start.gap-2 > .flex.items-center.justify-between {
  width: 100%;
}
.flex.items-center.justify-center.w-10.h-10.rounded-xl.shadow-sm.bg-warning\/10.text-warning {
  background: #921dc817;
  color: #c158ce;
}
.modal .scroll-area:before {
  top:-1px;
}

.bidi-chevron {
  /* [Doona] - transforms do not apply to non-replaced inline boxes; without
     this, the mirror silently no-ops on icons that sit in inline buttons. */
  display: inline-block;
}
.bidi-chevron:dir(rtl) {
  scale: -1 1;
}


/*
 * Chat extras: "load more" message enter animation, x-code wrapper colours, hidden supercharged toggles (YouTube / image generation), scroll-to-bottom button, collapsed reasoning preview, source button text wrap, and the newest reply's minimum height (added after the move).
 *
 * Moved unchanged from public_html/assets/css/custom-doona.css lines 3753–3823
 * (asset migration, Phase A). Its position in index.css is part of the
 * cascade; move it only together with a reorder-safety check.
 */
/* [Doona:START] - Soft enter animation for messages appended via "Load more".
   Only the newly loaded message containers get this class (cleared in JS
   after ~600ms), so existing messages stay completely still — no fade or
   translate on content the user is already reading. */
.doona-msg-enter {
  animation: doona-msg-enter 320ms cubic-bezier(0.22, 1, 0.36, 1) both;
  transform-origin: top;
}

@keyframes doona-msg-enter {
  0% {
    opacity: 0;
    transform: translateY(-8px);
  }
  100% {
    opacity: 1;
    transform: translateY(0);
  }
}
/* [Doona:END] */
/* [Doona] - (removed) the per-mode x-code .code-wrapper colours. A code
   block is now one fill-4 surface (code.css); a second, opaque wrapper colour
   inside it drew a box within the box. */

/* [Doona:START] - Hide YouTube analysis & AI image generation toggles in the
   "supercharged" tools modal. Keeps the underlying logic intact while removing
   the rows from the UI. Targets the literal Alpine `@change` attribute that
   Alpine leaves on the DOM after init. */
.modal label:has(input[\@change="toggle('youtube')"]),
.modal label:has(input[\@change="toggle('generate_image')"]) {
  display: none !important;
}
/* [Doona:END] */

/* [Doona:START] - ChatGPT-style "scroll to bottom" button above the composer.
   The wrapper uses pointer-events-none to let clicks fall through onto the
   gradient, while the button itself re-enables pointer events. A subtle
   backdrop blur + mode-aware shadow keep it readable on top of any content. */
/* [Doona] - Glass: the button is the thin glass chip (components/glass.css
   owns its background, blur, shadow and hover/press overlay). It no longer
   lifts 2px or swaps its shadow on hover: a blurred element should not
   move, and the glass shadow carries the soft inner glow. Press settles. */
.doona-scroll-bottom-btn:active {
  transform: scale(0.96);
}
/* [Doona:END] */
.message .duration-300.ease-out:not(.mt-2) .pb-5.text-content-dimmed x-markdown[size=sm]>div>p:nth-of-type(n+3), .message .duration-300.ease-out .pb-5.text-content-dimmed .line-clamp-2 x-markdown[size=sm]>div>p:nth-of-type(n+3) {
  display: none;
}
.message button.text-sm.text-content-dimmed > .truncate{
  white-space: normal;
}

/* [Doona:START] - The newest reply's minimum height (was the Tailwind
   last:min-h-[calc(100dvh-18rem)] lg:last:min-h-[calc(100dvh-15.5rem)] on
   the node in templates/app/chat.twig): a new turn starts at the top of the
   view with room below for the answer. --dn-turn-head is the height of the
   user's message above it plus the gap (chat.js _sizeTurn), so that message
   stays in view instead of being pushed just above it. */
[data-dn-turns] > [data-dn-turn]:last-child {
  min-block-size: max(0px, calc(100dvh - 18rem - var(--dn-turn-head, 0px)));
}

@media (min-width: 64rem) {
  [data-dn-turns] > [data-dn-turn]:last-child {
    min-block-size: max(0px, calc(100dvh - 15.5rem - var(--dn-turn-head, 0px)));
  }
}
/* [Doona:END] */

/*
 * Doona model avatar (x-avatar[mask=".../doona.svg"]): white circle + black logo in dark mode, dark circle in light mode.
 * Only while it is still a mask: with its colour tile (.has-brand) the disc stays off.
 *
 * Moved unchanged from public_html/assets/css/custom-doona.css lines 3824–3845
 * (asset migration, Phase A). Its position in index.css is part of the
 * cascade; move it only together with a reorder-safety check.
 */
/* ============================================
   Doona Avatar: dark mode = white circle + black logo
                 light mode = dark circle + white logo
   ============================================ */

/* Dark mode (default): white background circle */
x-avatar[mask="/assets/icons/monochrome/doona.svg"]:not(.has-brand) {
  background: #ffffff !important;
  --tw-gradient-from: #ffffff !important;
  --tw-gradient-to: #ffffff !important;
}

/* Dark mode: black logo (mask fill color) */
x-avatar[mask="/assets/icons/monochrome/doona.svg"] > .mask {
  background: #111111 !important;
}

/* Light mode: dark background circle */
html[data-mode="light"] x-avatar[mask="/assets/icons/monochrome/doona.svg"]:not(.has-brand) {
  background: #383a42f0 !important;
}


/*
 * Floating account menu card (dam-*): Alpine transitions, backdrop, avatar clone, profile / mode / workspace sections, menu items with icon chips, logout, policies.
 *
 * Moved unchanged from public_html/assets/css/custom-doona.css lines 3846–4113
 * (asset migration, Phase A). Its position in index.css is part of the
 * cascade; move it only together with a reorder-safety check.
 */
/* [Doona:START] - Floating account menu card (dam-*) */

/* Alpine transition helpers */
.dam-t-enter { transition: opacity 0.2s ease, transform 0.2s cubic-bezier(0.16, 1, 0.3, 1); }
.dam-t-leave { transition: opacity 0.15s ease, transform 0.15s ease; }
.dam-t-backdrop-from { opacity: 0; }
.dam-t-backdrop-to   { opacity: 1; }
.dam-t-card-from { opacity: 0; transform: scale(0.95) translateY(-6px); }
.dam-t-card-to   { opacity: 1; transform: scale(1)    translateY(0); }

/* Backdrop */
.dam-backdrop {
    position: fixed;
    inset: 0;
    z-index: 199;
    background: var(--elev-scrim);
    backdrop-filter: blur(2px);
    -webkit-backdrop-filter: blur(2px);
}

/* Crisp avatar clone (sits above the blurred backdrop) */
.dam-avatar-clone {
    position: fixed;
    z-index: 200;
    padding: 0;
    border: none;
    background: none;
    cursor: pointer;
    line-height: 0;
    border-radius: 50%;
    /* [Doona] - Elevation: was a 2.5px orange ring (a line). The clone sits
       crisp above the dimmed page, and that alone says "this is what opened
       the card". */
    box-shadow: none;
}
.dam-avatar-clone:focus-visible {
    outline: 2px solid var(--elev-focus-ring);
    outline-offset: 2px;
}

/* Card */
.dam-card {
    position: fixed;
    top: 68px;
    right: 16px;
    width: 272px;
    z-index: 201;
    overflow: hidden;
    border-radius: 20px;
    transform-origin: top right;
    /* [Doona] - Elevation: a popover — surface-2 + one soft shadow
       (shadow-2). The 1px border and the 1px ring shadow (two lines) and the
       stacked three-layer shadow are gone. In dark it was #1C1D20, darker
       than surface-2; raised layers are lighter. */
    background: var(--elev-surface-2);
    border: 0;
    box-shadow: var(--elev-shadow-2);
}

/* Profile section */
.dam-profile-section {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 16px;
    background: linear-gradient(135deg, rgba(245, 138, 6, 0.07) 0%, transparent 100%);
}
html[data-mode="dark"] .dam-profile-section {
    background: linear-gradient(135deg, rgba(245, 138, 6, 0.09) 0%, transparent 100%);
}
.dam-profile-link {
    display: flex;
    align-items: center;
    gap: 10px;
    text-decoration: none;
    min-width: 0;
    flex: 1;
}
.dam-profile-avatar {
    width: 44px !important;
    height: 44px !important;
    flex-shrink: 0;
}
.dam-profile-text { min-width: 0; }
.dam-profile-name {
    font-size: 14px;
    font-weight: 600;
    color: var(--color-content);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.dam-profile-phone {
    font-size: 12px;
    color: var(--color-content-dimmed);
    margin-top: 2px;
    direction: ltr;
    text-align: right;
    display: block;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Mode toggle: a gray (fill-3) round button, 36px paint, 44px hit area. */
.dam-mode-btn {
    position: relative;
    width: 36px;
    height: 36px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--elev-fill-3);
    color: var(--color-content-dimmed);
    border: none;
    cursor: pointer;
    touch-action: manipulation;
    -webkit-tap-highlight-color: transparent;
    transition: background-color 0.15s, transform 0.12s cubic-bezier(.32, .72, 0, 1);
    flex-shrink: 0;
}
.dam-mode-btn::after { content: ""; position: absolute; inset: -4px; }
.dam-mode-btn:hover { background: var(--elev-fill-2); color: var(--color-content); }
.dam-mode-btn:active { background: var(--elev-fill-1); transform: scale(0.94); transition: none; }

/* Workspace section.
   [Doona] - Elevation: it was set apart by a rule above and below. It is now
   its own group-filled block inset in the card, which separates it from the
   profile and the menu by fill and space instead. */
.dam-workspace-section {
    display: flex;
    align-items: center;
    gap: 10px;
    margin: 0 8px;
    padding: 10px 12px;
    border-radius: 14px;
    background: var(--elev-group);
}
.dam-workspace-link {
    display: flex;
    align-items: center;
    gap: 8px;
    text-decoration: none;
    min-width: 0;
    flex: 1;
}
.dam-workspace-avatar {
    width: 30px !important;
    height: 30px !important;
    flex-shrink: 0;
}
.dam-workspace-text { min-width: 0; }
.dam-workspace-name {
    font-size: 13px;
    font-weight: 500;
    color: var(--color-content);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.dam-workspace-plan {
    font-size: 11px;
    /* Was #9CA3AF: 2.5:1 on white. */
    color: var(--color-content-dimmed);
    margin-top: 1px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.dam-workspace-switch {
    position: relative;
    width: 34px;
    height: 34px;
    border-radius: 10px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--elev-fill-3);
    color: var(--color-content-dimmed);
    border: none;
    cursor: pointer;
    font-size: 15px;
    touch-action: manipulation;
    -webkit-tap-highlight-color: transparent;
    transition: background-color 0.15s, transform 0.12s cubic-bezier(.32, .72, 0, 1);
    flex-shrink: 0;
}
/* 34px paint, 44px hit area. */
.dam-workspace-switch::after { content: ""; position: absolute; inset: -5px; }
.dam-workspace-switch:hover { background: var(--elev-fill-2); color: var(--color-content); }
.dam-workspace-switch:active { background: var(--elev-fill-1); transform: scale(0.94); transition: none; }

/* Menu section */
.dam-menu-section { padding: 8px; }

/* Menu item */
.dam-item {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 9px 10px;
    border-radius: 12px;
    font-size: 13.5px;
    font-weight: 500;
    color: var(--color-content);
    text-decoration: none;
    transition: background-color 0.15s;
    cursor: pointer;
    touch-action: manipulation;
    -webkit-tap-highlight-color: transparent;
}
/* [Doona] - The logout item is a <button> because /logout is a POST. An <a>
   with display:flex fills its parent; a button shrinks to its content and
   centres its text, so both are restored here. Colour and metrics still come
   from .dam-item above. */
button.dam-item {
    width: 100%;
    text-align: start;
    background: none;
    border: 0;
    font-family: inherit;
}
.dam-item:hover { background: var(--elev-hover); text-decoration: none; }
/* Pointer-down, not click. */
.dam-item:active { background: var(--elev-pressed); transition: none; }

/* Icon chips */
.dam-item-icon {
    width: 30px;
    height: 30px;
    border-radius: 8px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 15px;
    flex-shrink: 0;
}
.dam-item-icon--blue   { background: rgba(59,  130, 246, 0.12); color: #3B82F6; }
.dam-item-icon--orange { background: rgba(245, 138,   6, 0.12); color: #F59E0B; }
.dam-item-icon--purple { background: rgba(139,  92, 246, 0.12); color: #8B5CF6; }
.dam-item-icon--green  { background: rgba(16,  185, 129, 0.12); color: #10B981; }
.dam-item-icon--teal   { background: rgba(20,  184, 166, 0.12); color: #14B8A6; }
.dam-item-icon--red    { background: rgba(239,  68,  68, 0.10); color: #EF4444; }
html[data-mode="dark"] .dam-item-icon--blue   { background: rgba(59,  130, 246, 0.15); }
html[data-mode="dark"] .dam-item-icon--orange { background: rgba(245, 138,   6, 0.15); }
html[data-mode="dark"] .dam-item-icon--purple { background: rgba(139,  92, 246, 0.15); }
html[data-mode="dark"] .dam-item-icon--green  { background: rgba(16,  185, 129, 0.15); }
html[data-mode="dark"] .dam-item-icon--teal   { background: rgba(20,  184, 166, 0.15); }
html[data-mode="dark"] .dam-item-icon--red    { background: rgba(239,  68,  68, 0.12); color: #F87171; }

/* Logout is destructive: its own group, behind an inset hairline (menus
   only, DESIGN-ELEVATION §2.1), like the desktop menu's trash items. */
.dam-item--logout {
    position: relative;
    margin-top: 9px;
}
.dam-item--logout::before {
    content: "";
    pointer-events: none;
    position: absolute;
    top: -5px;
    inset-inline: 12px;
    height: 1px;
    background: var(--elev-separator);
}
/* [Doona] - Light: #DC2626, 4.8:1 on the white card (#EF4444 was 3.76:1).
   The icon chip keeps the brighter red: a glyph needs 3:1, a label 4.5:1. */
.dam-item--logout { color: #DC2626; }
html[data-mode="dark"] .dam-item--logout { color: #F87171; }
.dam-item--logout:hover { background: rgba(239, 68, 68, 0.08) !important; }
.dam-item--logout:active { background: rgba(239, 68, 68, 0.14) !important; }

/* Policies */
.dam-policies {
    position: relative;
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    /* A major section of the menu: set apart by the menu gap band, edge to
       edge, the way the desktop account menu sets apart its footer links
       (menus are the one place separators are allowed, DESIGN-ELEVATION
       §2.1). */
    margin-top: 4px;
    padding: 18px 18px 16px;
}
.dam-policies::before {
    content: "";
    position: absolute;
    top: 0;
    inset-inline: 0;
    height: 8px;
    background: var(--elev-separator-gap);
}
.dam-policies a { font-size: 11px; color: var(--color-content-dimmed); text-decoration: none; }
.dam-policies a:hover { color: var(--color-content); text-decoration: underline; }

/* [Doona:END] */


/*
 * Mobile nav side drawer (dnm-*): transitions, backdrop, drawer, logo, header, close button, nav list items, footer.
 *
 * Moved unchanged from public_html/assets/css/custom-doona.css lines 4114–4294
 * (asset migration, Phase A). Its position in index.css is part of the
 * cascade; move it only together with a reorder-safety check.
 */
/* [Doona:START] - Nav side drawer (dnm-*) */

.dnm-t-fade-enter { transition: opacity 0.25s ease; }
.dnm-t-fade-leave { transition: opacity 0.2s ease; }
.dnm-t-fade-from  { opacity: 0; }
.dnm-t-fade-to    { opacity: 1; }

.dnm-t-slide-enter { transition: transform 0.32s cubic-bezier(0.16, 1, 0.3, 1); }
.dnm-t-slide-leave { transition: transform 0.22s cubic-bezier(0.7, 0, 1, 1); }
.dnm-t-slide-from  { transform: translateX(100%); }
.dnm-t-slide-to    { transform: translateX(0); }

.dnm-t-reveal-enter { transition: opacity 0.18s ease, transform 0.18s ease; }
.dnm-t-reveal-leave { transition: opacity 0.14s ease, transform 0.14s ease; }
.dnm-t-reveal-from  { opacity: 0; transform: translateY(-4px); }
.dnm-t-reveal-to    { opacity: 1; transform: translateY(0); }

/* Backdrop: the shared scrim — the drawer is modal, so the page dims. */
.dnm-backdrop {
    position: fixed;
    inset: 0;
    z-index: 198;
    background: var(--elev-scrim);
    backdrop-filter: blur(2px);
    -webkit-backdrop-filter: blur(2px);
}

/* Drawer.
   [Doona] - Elevation: a sheet over the page — surface-2 over the scrim,
   with one soft shadow (shadow-2, the lowest that reads) as its only edge. The 1px start border and the inset white
   highlight (both lines) are gone. The orange glow in the top corner is gone
   too: it was decoration, and the translucent group-fill rows over it read
   as gradient rows. The sheet is one plain surface. */
.dnm-drawer {
    position: fixed;
    top: 0;
    right: 0;
    width: min(332px, 90vw);
    height: 100dvh;
    z-index: 199;
    display: flex;
    flex-direction: column;
    background: var(--elev-surface-2);
    border-radius: 24px 0 0 24px;
    box-shadow: var(--elev-shadow-2);
    overflow: hidden;
}

/* Logo in drawer header */
.dnm-logo-link { display: flex; align-items: center; }
.dnm-logo-dark,
.dnm-logo-light { width: 120px; height: auto; }
.dnm-logo-dark  { display: none; }
.dnm-logo-light { display: block; }
html[data-mode="dark"] .dnm-logo-dark  { display: block; }
html[data-mode="dark"] .dnm-logo-light { display: none; }

/* Drawer header */
.dnm-drawer-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 14px;
    padding: 20px 18px 14px;
    flex-shrink: 0;
}

.dnm-drawer-title {
    font-size: 15px;
    font-weight: 600;
    color: #111827;
}
html[data-mode="dark"] .dnm-drawer-title { color: #F9FAFB; }

.dnm-close-btn {
    position: relative;
    width: 36px;
    height: 36px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--elev-fill-3);
    color: var(--color-content-dimmed);
    border: 0;
    cursor: pointer;
    font-size: 16px;
    touch-action: manipulation;
    -webkit-tap-highlight-color: transparent;
    transition: background 0.15s ease, color 0.15s ease, transform 0.12s cubic-bezier(.32, .72, 0, 1);
}
/* 36px paint, 44px hit area. */
.dnm-close-btn::after { content: ""; position: absolute; inset: -4px; }
.dnm-close-btn:hover { background: var(--elev-fill-2); color: var(--color-content); }
.dnm-close-btn:active { background: var(--elev-fill-1); transform: scale(0.94); transition: none; }

/* Nav content area */
.dnm-nav-content {
    flex: 1;
    overflow-y: auto;
    padding: 8px 0 12px;
    scrollbar-width: thin;
    scrollbar-color: rgba(148, 163, 184, 0.45) transparent;
}
.dnm-nav-content nav {
    gap: 6px !important;
    padding: 0 14px !important;
}
.dnm-nav-content h4 {
    padding: 12px 8px 6px !important;
    font-size: 12px !important;
    /* Was #9CA3AF (2.5:1 on white) and #6B7280 in dark (3.3:1): the section
       labels are secondary text, so they take the secondary label colour. */
    color: var(--color-content-dimmed) !important;
    font-weight: 600 !important;
    letter-spacing: 0.05em;
    text-transform: uppercase;
}

/* List items.
   [Doona] - Elevation: each row was a white card with a 1px rim and its own
   drop shadow, and hover drew an orange rim. Rows are now group fills (one
   step up from the sheet, no rim, no shadow): hover = group-hover, press =
   the pressed fill, instantly. The current page keeps the brand tint, which
   no neutral state can be mistaken for. 50px tall: above the touch floor. */
.dnm-nav-item {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 11px;
    margin-bottom: 5px;
    border-radius: 16px;
    background: var(--elev-group);
    border: 0;
    box-shadow: none;
    transition: background-color 0.15s ease, transform 0.12s cubic-bezier(.32, .72, 0, 1);
    color: var(--color-content);
    text-decoration: none;
    touch-action: manipulation;
    -webkit-tap-highlight-color: transparent;
}
.dnm-nav-item:hover {
    background: var(--elev-group-hover);
    text-decoration: none;
}
.dnm-nav-item:active {
    background: var(--elev-pressed);
    transform: scale(0.985);
    transition: none;
}
.dnm-nav-item > div:first-child {
    width: 34px !important;
    height: 34px !important;
}
.dnm-nav-item--active,
.dnm-nav-item--active:hover {
    background: color-mix(in oklab, var(--color-gradient-from, rgb(245 138 6)) 14%, transparent) !important;
    color: #9A4A06 !important;
}
html[data-mode="dark"] .dnm-nav-item--active,
html[data-mode="dark"] .dnm-nav-item--active:hover {
    background: color-mix(in oklab, var(--color-gradient-from, rgb(245 138 6)) 20%, transparent) !important;
    color: #FDBA74 !important;
}

/* Drawer footer */
.dnm-drawer-footer {
    display: flex;
    flex-direction: column;
    gap: 10px;
    flex-shrink: 0;
    padding: 12px 14px calc(14px + env(safe-area-inset-bottom));
    /* The sheet's own surface: the footer is set apart by space, not by a
       band of a different colour. */
    background: transparent;
}


/*
 * Nav drawer invite card (dnm-invite-*) and the .doona-scroll-target scroll offset used by the profile page it links to.
 *
 * Moved unchanged from public_html/assets/css/custom-doona.css lines 4295–4395
 * (asset migration, Phase A). Its position in index.css is part of the
 * cascade; move it only together with a reorder-safety check.
 */
.dnm-invite-card {
    position: relative;
    display: flex;
    gap: 12px;
    overflow: hidden;
    padding: 14px;
    border-radius: 20px;
    color: #ffffff;
    background:
        radial-gradient(circle at 18% 16%, rgba(255, 255, 255, 0.28), transparent 26%),
        linear-gradient(135deg, #FFB562 0%, #F58A06 52%, #C96A02 100%);
    /* [Doona] - Elevation: was a 5px orange glow round the card (a coloured
       edge). The card is a solid fill; it needs no edge at all. */
    box-shadow: none;
    cursor: pointer;
    text-decoration: none;
    touch-action: manipulation;
    -webkit-tap-highlight-color: transparent;
    transition: opacity 0.18s ease, transform 0.12s cubic-bezier(.32, .72, 0, 1);
}
.dnm-invite-card:hover {
    opacity: 0.92;
    text-decoration: none;
    color: #ffffff;
}
.dnm-invite-card:active {
    transform: scale(0.985);
    transition: none;
}
.dnm-invite-card::after {
    content: "";
    position: absolute;
    inset-inline-end: -28px;
    bottom: -34px;
    width: 118px;
    height: 118px;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.14);
}
.dnm-invite-icon {
    position: relative;
    z-index: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 42px;
    height: 42px;
    border-radius: 15px;
    background: rgba(255, 255, 255, 0.22);
    font-size: 22px;
    flex-shrink: 0;
}
.dnm-invite-body {
    position: relative;
    z-index: 1;
    min-width: 0;
    flex: 1;
}
.dnm-invite-title {
    font-size: 14px;
    font-weight: 700;
}
.dnm-invite-body p {
    margin: 4px 0 0;
    font-size: 12px;
    line-height: 1.8;
    color: rgba(255, 255, 255, 0.82);
}
.dnm-invite-arrow {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    min-height: 32px;
    border-radius: 999px;
    font-size: 12px;
    font-weight: 700;
    text-decoration: none;
    cursor: pointer;
}
.dnm-invite-arrow {
    position: relative;
    z-index: 1;
    align-self: center;
    width: 36px;
    min-width: 36px;
    color: #B45309;
    background: #ffffffeb;
    box-shadow: none;
}
.dnm-invite-arrow:hover {
    color: #92400E;
    background: #FFF7ED;
    text-decoration: none;
}
html[data-mode="dark"] .dnm-invite-arrow {
    color: #B45309;
    background: #ffffffeb;
}
html[data-mode="dark"] .dnm-invite-arrow:hover {
    color: #92400E;
    background: #FFF7ED;
}

.doona-scroll-target {
    scroll-margin-top: 90px;
}


/*
 * Nav drawer quick dock (dnm-quick-*): icon row incl. mode-switcher, content panel, info, action buttons, dark mode.
 *
 * Moved unchanged from public_html/assets/css/custom-doona.css lines 4396–4578
 * (asset migration, Phase A). Its position in index.css is part of the
 * cascade; move it only together with a reorder-safety check.
 */
/* [Doona] - Elevation: the dock is a group fill on the sheet (no rim, no
   blur needed on an opaque sheet); the chosen icon is a segmented-control
   thumb (a surface step, no shadow); the expanded row is one more group step; the small action buttons
   are gray (fill-3) and orange buttons. No borders anywhere. Each shortcut
   is a glyph with a short label under it (a tab-bar item), 54px tall and a
   fifth of the row wide, so the whole tile is the target. */
.dnm-quick-dock {
    background: var(--elev-group);
    border: 0;
    border-radius: 16px;
    overflow: hidden;
    width: 100%;
    margin: 4px auto 0;
    transition: background-color 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

.dnm-quick-icons {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 2px;
    padding: 4px;
}
.dnm-quick-icons mode-switcher {
    display: flex;
    flex: 1 1 0;
    min-width: 0;
}

.dnm-quick-icon {
    position: relative;
    display: inline-flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 3px;
    flex: 1 1 0;
    min-width: 0;
    height: 54px;
    border-radius: 12px;
    color: var(--color-content-dimmed);
    background: transparent;
    border: none;
    font-size: 20px;
    cursor: pointer;
    touch-action: manipulation;
    -webkit-tap-highlight-color: transparent;
    transition: background-color 0.15s ease, color 0.15s ease, transform 0.12s cubic-bezier(.32, .72, 0, 1);
}
.dnm-quick-icons mode-switcher .dnm-quick-icon { width: 100%; }
.dnm-quick-icon > .ti { line-height: 1; }
.dnm-quick-label {
    font-size: 11px;
    font-weight: 500;
    line-height: 1.2;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 100%;
}
.dnm-quick-icon.is-active {
    color: var(--color-content);
    background: var(--elev-thumb);
    box-shadow: var(--elev-shadow-1); /* raised selected: the thumb must read on its track */
}
@media (hover: hover) {
    .dnm-quick-icon:not(.is-active):hover {
        color: var(--color-content);
        background: var(--elev-hover);
    }
}
.dnm-quick-icon:active {
    background: var(--elev-pressed);
    transform: scale(0.94);
    transition: none;
}
.dnm-quick-icon.is-active:active { background: var(--elev-thumb); }

.dnm-quick-panel {
    padding: 0 8px 8px 8px;
}

.dnm-quick-content {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    background: var(--elev-group);
    border: 0;
    padding: 6px 8px;
    border-radius: 12px;
    animation: dnmQuickFade 0.2s ease forwards;
}

@keyframes dnmQuickFade {
    from { opacity: 0; transform: translateY(-2px); }
    to { opacity: 1; transform: translateY(0); }
}

.dnm-quick-info {
    display: flex;
    flex-direction: column;
    gap: 2px;
    overflow: hidden;
    flex-grow: 1;
    padding-right: 4px;
}

.dnm-quick-title {
    font-size: 10.5px;
    font-weight: 500;
    color: var(--color-content);
    white-space: nowrap;
}

.dnm-quick-url {
    font-size: 10px;
    /* Was #9CA3AF / #6B7280: under 3:1 on both sheets. */
    color: var(--color-content-dimmed);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    direction: ltr;
    text-align: left;
}

.dnm-quick-actions {
    display: flex;
    align-items: center;
    gap: 6px;
    flex-shrink: 0;
}

.dnm-quick-btn {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    border-radius: 9px;
    color: var(--color-content);
    background: var(--elev-fill-3);
    border: 0;
    font-size: 14px;
    cursor: pointer;
    touch-action: manipulation;
    -webkit-tap-highlight-color: transparent;
    transition: background-color 0.15s ease, transform 0.12s cubic-bezier(.32, .72, 0, 1);
    text-decoration: none;
}
.dnm-quick-btn::after { content: ""; position: absolute; inset: -6px -3px; }
.dnm-quick-btn:hover {
    background: var(--elev-fill-2);
    color: var(--color-content);
}
.dnm-quick-btn:active {
    background: var(--elev-fill-1);
    transform: scale(0.94);
    transition: none;
}

.dnm-quick-btn--primary,
.dnm-quick-btn--primary:hover {
    background: #F58A06;
    color: #FFFFFF;
}
.dnm-quick-btn--primary:hover { background: #E07D04; }
.dnm-quick-btn--primary:active { background: #C96A02; }


/* [Doona:END] */

/*
 * Mobile header history button and the header-specific credit button override.
 *
 * Moved unchanged from public_html/assets/css/custom-doona.css lines 4579–4624
 * (asset migration, Phase A). Its position in index.css is part of the
 * cascade; move it only together with a reorder-safety check.
 */
/* [Doona:START] - Scroll edge.
   The header sits above #content, which is the scroll container. At rest the
   two are one surface; once the content scrolls under the header a soft
   shadow (the .scroll-edge shadow, never a rule) says there is more above.
   main.twig toggles .is-scrolled from #content's scroll position. */
.doona-mobile-header {
    transition: box-shadow 0.2s ease;
}
.doona-mobile-header.is-scrolled {
    box-shadow: var(--elev-shadow-edge);
}
/* [Doona:END] */

/* [Doona:START] - Mobile header history button.
   [Doona] - Elevation: a gray (fill-3) pill with a hover and an instant press
   state. Every control in the header row (avatar, credit, private, history)
   paints 40px tall; ::after takes the hit area to the 44px touch floor, so
   overflow must stay visible. */
.doona-mobile-header .doona-history-btn {
    position: relative;
    min-height: 40px;
    transition: background-color 0.15s ease, transform 0.12s cubic-bezier(.32, .72, 0, 1);
    background: var(--elev-fill-3);
    border: none;
    color: var(--color-content-dimmed); /* [Doona] - G5 */
    font-weight: 300;
    box-shadow: none;
    touch-action: manipulation;
    -webkit-tap-highlight-color: transparent;
}
.doona-mobile-header .doona-history-btn::after {
    content: "";
    position: absolute;
    inset: -2px;
}
/* The history mark: the same 14px glyph size as the private toggle's. */
.doona-mobile-header .doona-history-btn__icon {
    font-size: 14px;
    margin-inline-end: 3px;
}
.doona-mobile-header .doona-history-btn:hover { background: var(--elev-fill-2); }
.doona-mobile-header .doona-history-btn:active {
    background: var(--elev-fill-1);
    transform: scale(0.97);
    transition: none;
}
/* [Doona:END] */

/* [Doona:START] - Mobile header credit button override.
   [Doona] - Elevation: one recipe for the credit button everywhere — a
   brand-tinted fill, no rim, no coloured glow (the desktop sidebar one is in
   credit-button.css). The old light-mode solid #FFA353 carried white text at
   2.0:1; on the tint the text is the content colour. */
.doona-mobile-header a.button-outline.remcredit[href="app/billing"],
.doona-mobile-header a.button-outline.nocredit[href="app/billing/packs"] {
    position: relative;
    min-height: 40px;
    transition: background-color 0.15s ease, transform 0.12s cubic-bezier(.32, .72, 0, 1);
    transform: none;
    background: color-mix(in oklab, var(--color-gradient-from, rgb(245 138 6)) 18%, transparent);
    border: none;
    color: var(--color-content);
    padding: 5px 15px;
    border-radius: 20px;
    font-weight: 400;
    box-shadow: none;
    text-shadow: none;
}

html[data-mode="dark"] .doona-mobile-header a.button-outline.remcredit[href="app/billing"],
html[data-mode="dark"] .doona-mobile-header a.button-outline.nocredit[href="app/billing/packs"] {
    background: color-mix(in oklab, var(--color-gradient-from, rgb(245 138 6)) 30%, transparent);
}
.doona-mobile-header a.button-outline.remcredit[href="app/billing"]:hover,
.doona-mobile-header a.button-outline.nocredit[href="app/billing/packs"]:hover {
    background: color-mix(in oklab, var(--color-gradient-from, rgb(245 138 6)) 24%, transparent);
    transform: none;
    box-shadow: none;
}
html[data-mode="dark"] .doona-mobile-header a.button-outline.remcredit[href="app/billing"]:hover,
html[data-mode="dark"] .doona-mobile-header a.button-outline.nocredit[href="app/billing/packs"]:hover {
    background: color-mix(in oklab, var(--color-gradient-from, rgb(245 138 6)) 36%, transparent);
}
.doona-mobile-header a.button-outline.remcredit[href="app/billing"]:active,
.doona-mobile-header a.button-outline.nocredit[href="app/billing/packs"]:active {
    transform: scale(0.97);
    transition: none;
}
.doona-mobile-header a.button-outline.remcredit[href="app/billing"] > x-credit,
.doona-mobile-header a.button-outline.nocredit[href="app/billing/packs"] > x-credit,
.doona-mobile-header a.button-outline.remcredit[href="app/billing"]:hover > x-credit,
.doona-mobile-header a.button-outline.nocredit[href="app/billing/packs"]:hover > x-credit {
    color: var(--color-content);
    text-shadow: none;
    transform: none;
}
/* [Doona:END] */

/*
 * Light-mode white logo for the Doona model avatar (the last rule of custom-doona.css; split from components/doona-avatar.css only because of source order).
 *
 * Moved unchanged from public_html/assets/css/custom-doona.css lines 4625–4628
 * (asset migration, Phase A). Its position in index.css is part of the
 * cascade; move it only together with a reorder-safety check.
 */
/* Light mode: white logo (mask fill color) */
html[data-mode="light"] x-avatar[mask="/assets/icons/monochrome/doona.svg"] > .mask {
  background: #ffffff !important;
}

/*
 * Desktop sidebar shell (aside.sticky): glass background per mode, header row, mode-switcher / icon buttons, nav links and active item, scrollbar, workspace block, staggered entry delays, ≤1024px background, workspace switcher button text.
 *
 * Moved unchanged from public_html/assets/css/doona-styles.css lines 1–203
 * (asset migration, Phase A). Its position in index.css is part of the
 * cascade; move it only together with a reorder-safety check.
 */
aside.sticky {
  background: linear-gradient(135deg,
          rgba(255, 255, 255, 0.1) 0%,
          rgba(255, 255, 255, 0.05) 100%);
  /* [Doona] - Glass: no backdrop-filter. The sidebar is an opaque
     surface-1 (set per mode below), so the blur painted nothing but cost a
     full-height filter pass, and it made the sidebar a backdrop root that
     clipped the glass of any menu opened inside it. */
  /* [Doona] - Elevation: no edge line; the sidebar is told apart from the
     content by its surface (surface-1 vs the page). */
  border-right: 0;
  transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
  width: calc(var(--spacing) * 70) !important;
  position: relative;
}

html[data-mode="dark"] aside.sticky {
  background: var(--elev-surface-1);
}

html[data-mode="light"] aside.sticky {
  background: var(--elev-surface-1);
}

aside.sticky:hover {
  transform: translateX(0);
}

aside.sticky .relative.flex.items-center.justify-between.px-4 {
  background: transparent;
  border: none;
  border-radius: 16px;
  margin: 0 8px;
  padding: 10px;
  transition: 0.3s;
}

aside.sticky .relative.flex.items-center.justify-between.px-4:hover {
  background: transparent;
  box-shadow: none;
}

aside.sticky .relative.flex.items-center.justify-between.px-4>a {
  overflow: visible;
  /* [Doona] - The header row also holds the admin link, the private-mode
     toggle and the theme button: the logo gives way (scales down inside its
     link) instead of painting over the buttons. */
  min-width: 0;
  flex: 0 1 auto;
}

/* The logo is drawn at scale(1.3) with an 18px start margin
   (misc-rtl-icons-and-globals.css): size it so the SCALED image fits the
   link, and grow it from its start edge, not both ways. */
aside.sticky .relative.flex.items-center.justify-between.px-4>a img {
  max-width: calc((100% - 26px) / 1.3); /* 18px margin + 8px air */
  object-fit: contain;
  transform-origin: left center;
}

[dir="rtl"] aside.sticky .relative.flex.items-center.justify-between.px-4>a img {
  transform-origin: right center;
}

aside.sticky .relative.flex.items-center.justify-between.px-4>.flex {
  flex-shrink: 0;
}

aside.sticky mode-switcher button[type="button"],
aside.sticky .aside-icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 35px;
  min-width: 35px;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 12px;
  padding: 8px;
  text-decoration: none;
  color: inherit;
  transition: all 0.2s;
}

aside.sticky mode-switcher button[type="button"]:hover,
aside.sticky .aside-icon-btn:hover {
  background: linear-gradient(135deg,
          rgba(245, 138, 6, 0.2) 0%,
          rgba(245, 138, 6, 0.1) 100%);
  border-color: transparent;
}
/* [Doona] - Elevation: instant press feedback (pointer-down). */
aside.sticky mode-switcher button[type="button"]:active,
aside.sticky .aside-icon-btn:active {
  background: rgba(245, 138, 6, 0.28);
  transform: scale(0.94);
  transition: none;
}

aside.sticky nav,
aside.sticky .flex.flex-col.gap-4.px-4.mt-auto {
  z-index: -1;
  padding: 12px 16px;
  background: transparent;
  border: none;
}

aside.sticky nav a,
aside.sticky nav .button {
  padding: 6px 15px;
  border-radius: 8px;
  transition: 0s;
  position: relative;
  border: solid 1px transparent;
  overflow: hidden;
  transition: all 0.2s;
}

html[data-mode="light"] aside.sticky nav a:hover,
html[data-mode="light"] aside.sticky nav .button:hover {
  background: #ffffff;
  border-color: transparent;
}

html[data-mode="dark"] aside.sticky nav a:hover,
html[data-mode="dark"] aside.sticky nav .button:hover {
  background: var(--elev-hover);
  border-color: transparent;
}

aside.sticky nav a:not(.bg-main):hover,
aside.sticky nav .button:not(.bg-main):hover {
  background: var(--elev-hover) !important;
  box-shadow: none;
}

/* [Doona] - Elevation: light hover was white/.3 plus a shadow, which on
   the surface-1 sidebar was close to invisible. Both modes now use the hover
   fill above, and press uses the pressed fill, instantly. */
aside.sticky nav a:not(.bg-main):active,
aside.sticky nav .button:not(.bg-main):active {
  background: var(--elev-pressed) !important;
  transition: none;
}

/* [Doona] - Elevation: the selected nav item is a raised pill — light: a
   white pill on the surface-1 sidebar, which only reads with shadow-1 (the
   two surfaces are 1.04:1 apart); dark: the lighter selected fill. No rim.
   ("Raised selected" rule, DESIGN-ELEVATION.md §1.3.) */
html[data-mode="light"] aside.sticky nav a.bg-main, html[data-mode="light"] aside.sticky nav .button.bg-main{
  border: solid 1px transparent;
  background: var(--elev-surface-2);
  box-shadow: var(--elev-shadow-1);
}
html[data-mode="dark"] aside.sticky nav a.bg-main, html[data-mode="dark"] aside.sticky nav .button.bg-main{
  border: solid 1px transparent;
  background: var(--elev-selected);
}

aside.sticky::-webkit-scrollbar {
  width: 6px;
}

aside.sticky::-webkit-scrollbar-track {
  background: rgba(255, 255, 255, 0.05);
  border-radius: 3px;
}

aside.sticky::-webkit-scrollbar-thumb {
  background: linear-gradient(180deg,
          rgba(245, 138, 6, 0.6) 0%,
          rgba(245, 138, 6, 0.4) 100%);
  border-radius: 3px;
}

aside.sticky::-webkit-scrollbar-thumb:hover {
  background: linear-gradient(180deg,
          rgba(245, 138, 6, 0.8) 0%,
          rgba(245, 138, 6, 0.6) 100%);
}

aside.sticky > div.relative.mx-4{
  background: transparent;
  margin: 0 16px;
}

aside.sticky > div.relative.mx-4:hover{
  background: transparent;
}

aside.sticky > div.relative.mx-4 > button{
  padding-right: 10px;
  padding-left: 10px;
  border-radius: 16px;
  background: #ffffffbf;
  /* [Doona] - Elevation: the workspace switcher is a surface step (white on
     surface-1), no rim and no shadow. Its hover and press used Tailwind's
     hover:bg-main, which this unlayered background beat, so it had no hover
     at all; they are here now, as fill steps. */
  border-color: transparent;
  box-shadow: none;
  transition: background-color 0.15s ease, transform 0.12s cubic-bezier(.32, .72, 0, 1);
}
/* Light: white on surface-1 is 1.04:1 — the card dissolved into the column.
   shadow-1 gives it back its figure ("raised selected", §1.3). Dark keeps the
   surface step alone: there the step is wide enough. */
html[data-mode="light"] aside.sticky > div.relative.mx-4 > button{
  box-shadow: var(--elev-shadow-1);
}
html[data-mode="light"] aside.sticky > div.relative.mx-4 > button:hover,
html[data-mode="light"] aside.sticky > div.relative.mx-4 > .peer[data-open] + button {
  background: var(--elev-surface-2);
}
aside.sticky > div.relative.mx-4 > button:active {
  transform: scale(0.985);
  transition: none;
}

aside.sticky>*:nth-child(1) {
  animation-delay: 0.1s;
}

aside.sticky>*:nth-child(2) {
  animation-delay: 0.2s;
}

aside.sticky>*:nth-child(3) {
  animation-delay: 0.3s;
}

aside.sticky>*:nth-child(4) {
  animation-delay: 0.4s;
}

/* [Doona] - Elevation: at exactly 1024px both this and the desktop rules
   matched and the sidebar briefly got a dark glass gradient and a heavy
   shadow; it keeps its surface-1 and no shadow at every width. */
@media (max-width: 1024px) {
  aside.sticky {
      background: var(--elev-surface-1);
      box-shadow: none;
  }
}

aside button.flex.items-center.group.w-full.gap-2.p-2.text-start.border-line .whitespace-nowrap {
  max-width: unset;
}

aside button.flex.items-center.group.w-full.gap-2.p-2.text-start.border-line .whitespace-nowrap .text-xs.text-intermediate-content-dimmed {
  font-size: 12px !important;
}


/*
 * Workspace / user menu popovers: radius, position and width, text size, avatar colour, frosted background per mode.
 *
 * Moved unchanged from public_html/assets/css/doona-styles.css lines 204–242
 * (asset migration, Phase A). Its position in index.css is part of the
 * cascade; move it only together with a reorder-safety check.
 */
div[x-ref="wsmenu"], div[x-ref="usermenu"]{
  border-radius: 16px;
}

div[x-ref="wsmenu"]{
  right: 0;
  left: 0;
  width: 100%;
}

div[x-ref="usermenu"]{
  right: 0;
  left: -13px;
  width: 220px;
}

div[x-ref="wsmenu"] .text-xs.text-content-dimmed {
  font-size: 12px !important;
}

div[x-ref="wsmenu"] x-avatar {
  background-color: #383a42;
  color: #ffffff;
}

/* [Doona] - OWNER DECISION: these two sidebar menus keep their pre-redesign
   look (353598de4), not the elevation .menu surface: frosted glass (white/.6
   light, black/.7 dark, 10px blur), a 1px edge, and the old soft content-
   tinted shadow-xl. The no-lines rule does not apply to them
   (DESIGN-ELEVATION.md §2.1). Rows and <hr> are in user-workspace-menus.css. */
aside div[x-ref="wsmenu"],
aside div[x-ref="usermenu"] {
  border: 1px solid rgb(245 246 246);
  box-shadow:
    0 20px 25px -5px color-mix(in oklab, var(--color-content) 10%, transparent),
    0 8px 10px -6px color-mix(in oklab, var(--color-content) 10%, transparent);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
}
html[data-mode="light"] aside div[x-ref="wsmenu"],
html[data-mode="light"] aside div[x-ref="usermenu"] {
  background: rgba(255, 255, 255, 0.6);
}
html[data-mode="light"] aside div[x-ref="usermenu"] {
  border-color: rgb(227 228 228 / 53%);
}
html[data-mode="dark"] aside div[x-ref="wsmenu"],
html[data-mode="dark"] aside div[x-ref="usermenu"] {
  background: rgba(0, 0, 0, 0.7);
  border-color: #242424;
}


/*
 * Sidebar credit button height, dark workspace switcher button, nav list gaps (by viewport), mobile nav menu list, workspace avatar, aside bottom block.
 *
 * Moved unchanged from public_html/assets/css/doona-styles.css lines 243–280
 * (asset migration, Phase A). Its position in index.css is part of the
 * cascade; move it only together with a reorder-safety check.
 */
aside a.button[href="app/billing"] {
  height: 50px;
}

html[data-mode='dark'] aside button.flex.items-center.group.w-full.gap-2.p-2.text-start.border-line {
  /* [Doona] - Elevation: the workspace switcher is a group fill, no rim;
     hover and the open menu take the group-hover fill, press the pressed
     fill. */
  background: var(--elev-group);
  border-color: transparent;
  box-shadow: none;
}
html[data-mode='dark'] aside button.flex.items-center.group.w-full.gap-2.p-2.text-start.border-line:hover,
html[data-mode='dark'] aside .peer[data-open] + button.flex.items-center.group.w-full.gap-2.p-2.text-start.border-line {
  background: var(--elev-group-hover);
}
html[data-mode='dark'] aside button.flex.items-center.group.w-full.gap-2.p-2.text-start.border-line:active {
  background: var(--elev-pressed);
}

nav.flex.overflow-y-auto ul.flex.flex-col {
  gap: 8px;
}

@media (min-width: 1024px) {
  nav.flex.overflow-y-auto ul.flex.flex-col {
      gap: 10px;
  }
}

@media (max-height: 750px) {
  nav.flex.overflow-y-auto ul.flex.flex-col {
      gap: 6px;
  }
}

nav[x-ref="menu"] ul{
  display: flex;
  flex-direction: column;
  gap: 10px;
}

nav[x-ref="menu"] a[href="app/workspace"] x-avatar {
  background-color: #383a42;
  color: #ffffff;
}
aside.sticky .flex.flex-col.gap-4.px-4.mt-auto{
     margin-top: auto;
}

/*
 * Mobile footer (.mob-footer) bottom padding and height-dependent top margin.
 *
 * Moved unchanged from public_html/assets/css/doona-styles.css lines 281–297
 * (asset migration, Phase A). Its position in index.css is part of the
 * cascade; move it only together with a reorder-safety check.
 */
.mob-footer {
  padding-bottom: 60px;
}
@media (max-width: 1023px) {
  .mob-footer { margin-top: 4vh; }
}
@media (max-width: 1023px) and (max-height: 800px) {
  .mob-footer { margin-top: 5vh; }
}

@media (max-width: 1023px) and (max-height: 760px) {
  .mob-footer { margin-top: 6vh; }
}

@media (max-width: 1023px) and (max-height: 700px) {
  .mob-footer { margin-top: 7.5vh; }
}

/*
 * Private mode (F2): the on/off toggle (.dn-private-btn) in the sidebar
 * header and the mobile header, the top pill (.dn-private-bar /
 * .dn-private-pill), the first-time explainer,
 * the turn-off dialog icon, the Save / Saved affordances on temporary items
 * and the usage-log badge. The page-wide look is private-theme.css.
 *
 * Logical properties only (RTL today, LTR later). Both themes. No lines
 * (DESIGN-ELEVATION §0): fills and soft shadows only; the focus ring is the
 * one outline. The theme is a hint, never the only signal: the pill says it
 * in words, the toggle exposes aria-pressed.
 */

/* [Doona:START] - Private mode (F2) */
:root {
  --dn-private: #6d28d9;
  --dn-private-soft: rgba(109, 40, 217, 0.08);
  --dn-private-line: rgba(109, 40, 217, 0.28);
  --dn-private-ink: #4c1d95;
  --dn-private-soft-strong: rgba(109, 40, 217, 0.12);
  --dn-private-soft-hover: rgba(109, 40, 217, 0.18);
  --dn-private-pill-bg: #ffffff;
  /* The toggle when on (Tinted): text >= 6:1 on the fill, hover included,
     in both the normal and the private surfaces (dark: >= 8.5:1). */
  --dn-private-tint: rgba(124, 58, 237, 0.14);
  --dn-private-tint-hover: rgba(124, 58, 237, 0.20);
  --dn-private-tint-pressed: rgba(124, 58, 237, 0.26);
  --dn-private-tint-text: #5b21b6;
}

html[data-mode="dark"] {
  --dn-private: #c4b5fd;
  --dn-private-soft: rgba(196, 181, 253, 0.10);
  --dn-private-line: rgba(196, 181, 253, 0.30);
  --dn-private-ink: #ede9fe;
  --dn-private-soft-strong: rgba(196, 181, 253, 0.16);
  --dn-private-soft-hover: rgba(196, 181, 253, 0.24);
  --dn-private-pill-bg: rgb(40 32 70);
  --dn-private-tint: rgba(139, 92, 246, 0.28);
  --dn-private-tint-hover: rgba(139, 92, 246, 0.36);
  --dn-private-tint-pressed: rgba(139, 92, 246, 0.44);
  --dn-private-tint-text: #ddd6fe;
}

/* ---- The toggle (sidebar header + mobile header) -------------------------------
   Off it is exactly its neighbour: on desktop the theme button in the
   sidebar header (.aside-icon-btn in sidebar--shell.css), on the phone the
   history pill (.doona-history-btn in mobile-header.css). On it turns
   Tinted in the private violet with a heavier mark, so "on" reads at a
   glance. (Tabler 3.49 has no filled spy glyph; the stroke is thickened.)
   The compound selectors outrank those modules' own :hover / :active. */
.dn-private-btn {
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
}

.dn-private-btn[aria-busy="true"] {
  cursor: progress;
}

.dn-private-btn[aria-pressed="true"],
aside.sticky .aside-icon-btn.dn-private-btn[aria-pressed="true"],
.doona-mobile-header .doona-history-btn.dn-private-btn[aria-pressed="true"] {
  background: var(--dn-private-tint);
  color: var(--dn-private-tint-text);
}

.dn-private-btn[aria-pressed="true"]:hover,
aside.sticky .aside-icon-btn.dn-private-btn[aria-pressed="true"]:hover,
.doona-mobile-header .doona-history-btn.dn-private-btn[aria-pressed="true"]:hover {
  background: var(--dn-private-tint-hover);
  color: var(--dn-private-tint-text);
}

.dn-private-btn[aria-pressed="true"]:active,
aside.sticky .aside-icon-btn.dn-private-btn[aria-pressed="true"]:active,
.doona-mobile-header .doona-history-btn.dn-private-btn[aria-pressed="true"]:active {
  background: var(--dn-private-tint-pressed);
}

.dn-private-btn[aria-pressed="true"] .dn-private-btn__icon {
  -webkit-text-stroke: 0.6px currentColor;
  color: var(--dn-private-tint-text);
}

.dn-private-btn:focus-visible {
  outline: 2px solid var(--elev-focus-ring, var(--dn-private));
  outline-offset: 2px;
}

/* The header label is «حالت روح»; on a phone of 400px or less the row has
   no room for it beside history, credit and the menu, so it reads «روح».
   The button's accessible name stays the full one either way. */
.dn-private-btn__label-short {
  display: none;
}

@media (max-width: 400px) {
  .dn-private-btn--header .dn-private-btn__label {
    display: none;
  }

  .dn-private-btn--header .dn-private-btn__label-short {
    display: inline;
  }
}

/* The header button: the same 14px mark as the history clock. */
.dn-private-btn--header .dn-private-btn__icon {
  font-size: 14px;
  margin-inline-end: 3px;
}

/* The phone header holds avatar, credit, private and history in one row
   (and the menu button where main shows it). Below 401px the two pills
   (history and private, kept identical) tighten their padding and the
   credit button never wraps to two lines — only on a header that has the
   private toggle. */
@media (max-width: 400px) {
  .doona-mobile-header:has(.dn-private-btn) .doona-history-btn {
    padding-inline: 6px;
    gap: 2px;
  }

  .doona-mobile-header:has(.dn-private-btn) a.nocredit,
  .doona-mobile-header:has(.dn-private-btn) a.remcredit {
    white-space: nowrap;
  }
}

/* ---- "On" bar --------------------------------------------------------------- */
/* ---- The top pill ------------------------------------------------------------
   One calm indicator while the mode is on. Shown by CSS from
   <html data-private> alone: one source (paint() in private-mode.js, and
   base.twig on the first frame).

   It lives at the START of the content column (#content), away from the
   page toolbars, which sit at its end («چت جدید» / «تاریخچه», fixed
   top-4 end-10, pushed inward when the history drawer is open). The wrapper
   is sticky with no height, inside #content after the credit banner, so the
   pill sits under that banner when there is one, stays in view while the
   column scrolls, and moves nothing on the page. It floats: a fill and a
   soft shadow, no edge (DESIGN-ELEVATION §0, §1.3 shadow-2). */
.dn-private-bar {
  display: none !important;
}

html[data-private] .dn-private-bar {
  display: block !important;
}

.dn-private-bar {
  position: sticky;
  z-index: 25;
  inset-block-start: 0;
  block-size: 0;
  overflow: visible;
  pointer-events: none;
}

.dn-private-pill {
  position: absolute;
  inset-block-start: 14px;
  inset-inline-start: 16px;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-block-size: 36px;
  padding-block: 4px;
  padding-inline-start: 12px;
  padding-inline-end: 4px;
  border-radius: 999px;
  background: var(--elev-surface-2, var(--dn-private-pill-bg));
  box-shadow: var(--elev-shadow-2, 0 1px 2px rgb(0 0 0 / 0.06), 0 4px 16px rgb(0 0 0 / 0.10));
  color: var(--dn-private-ink);
  font-size: 0.8125rem;
  font-weight: 600;
  white-space: nowrap;
  pointer-events: auto;
}

.dn-private-pill > .ti {
  font-size: 1.125rem;
  color: var(--dn-private);
}

/* A Tinted button (never a bare label): the violet fill of the mode. */
.dn-private-pill__exit {
  position: relative;
  min-block-size: 28px;
  padding-inline: 12px;
  border-radius: 999px;
  border: 0;
  background: var(--dn-private-soft-strong);
  color: inherit;
  font: inherit;
  cursor: pointer;
  transition: background-color 0.15s ease, transform 0.1s ease;
}

/* A 44px hit area around the 28px button. */
.dn-private-pill__exit::before {
  content: "";
  position: absolute;
  inset: -8px -4px;
}

.dn-private-pill__exit:hover {
  background: var(--dn-private-soft-hover);
}

.dn-private-pill__exit:active {
  transform: scale(0.96);
}

.dn-private-pill__exit:focus-visible {
  outline: 2px solid var(--dn-private);
  outline-offset: 2px;
}

/* Where the page toolbar is. From lg it is fixed at the column's END, so
   the pill takes the start; when the canvas is open (any width) or the
   history drawer is open below 1440px, the toolbar is pushed inward far
   enough to reach the start, so the pill steps down under it (top-4 + 36px
   + room for its shadow) and keeps the mark and the button only — the label stays for
   screen readers. Offsets are from the wrapper, which sits under the red
   out-of-credits banner when there is one, so they hold with it too. */
@media (min-width: 1024px) {
  html[data-canvas="open"] .dn-private-pill {
    inset-block-start: 70px;
  }

  html[data-canvas="open"] .bg-rose-600 ~ .dn-private-bar .dn-private-pill {
    inset-block-start: 130px;
  }

  html[data-canvas="open"] .dn-private-pill__label {
    position: absolute;
    inline-size: 1px;
    block-size: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }
}

@media (min-width: 1024px) and (max-width: 1439.98px) {
  html[data-sidebar] .dn-private-pill {
    inset-block-start: 70px;
  }

  /* Under the red credit banner the toolbars carry 60px more top padding
     (history-sidebar--mobile.css), even once it has scrolled away. */
  html[data-sidebar] .bg-rose-600 ~ .dn-private-bar .dn-private-pill {
    inset-block-start: 130px;
  }

  html[data-sidebar] .dn-private-pill__label {
    position: absolute;
    inline-size: 1px;
    block-size: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }
}

/* (No pill any more, so the chat title keeps its own top.) */

/* Below lg the toolbar is in the flow at the column's START
   (misc-rtl-icons-and-globals.css): the pill moves to the end. On a phone
   it keeps its label (the button alone would say "turn off" with no
   object), only tighter. */
@media (max-width: 1023.98px) {
  .dn-private-pill {
    inset-inline-start: auto;
    inset-inline-end: 16px;
  }
}

@media (max-width: 639.98px) {
  .dn-private-pill {
    gap: 6px;
    padding-inline-start: 10px;
  }
}

/* ---- First-time explainer ------------------------------------------------------- */
.dn-private-intro__list {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin: 0;
  padding: 0;
  list-style: none;
  line-height: 1.7;
}

.dn-private-intro__list li {
  display: flex;
  align-items: flex-start;
  gap: 10px;
}

.dn-private-intro__list .ti {
  flex-shrink: 0;
  margin-block-start: 3px;
  font-size: 1.125rem;
  color: var(--dn-private);
}

/* ---- Turn-off dialog ------------------------------------------------------------ */
.dn-private-modal__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  inline-size: 40px;
  block-size: 40px;
  border-radius: 50%;
  background: var(--dn-private-soft);
  color: var(--dn-private);
  font-size: 1.25rem;
}

/* ---- Save / Saved / badge ----------------------------------------------------------- */
.dn-private-save {
  color: var(--dn-private);
}

.dn-private-save[disabled] {
  opacity: 0.6;
  cursor: progress;
}

.dn-private-saved,
.dn-private-badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding-block: 1px;
  padding-inline: 8px;
  border-radius: 999px;
  font-size: 0.75rem;
  font-weight: 500;
  white-space: nowrap;
}

.dn-private-saved {
  background: rgba(34, 197, 94, 0.08);
  color: #15803d;
}

html[data-mode="dark"] .dn-private-saved {
  color: #86efac;
}

.dn-private-badge {
  background: var(--dn-private-soft);
  color: var(--dn-private-ink);
}

/* [Doona:END] */

/*
 * Connectors (F3): the member's connector pages (/app/account/connectors,
 * /app/account/connections/{id}), the admin connector pages and the
 * catalogue import. New module, not moved from the legacy files.
 * Logical properties only (RTL today, LTR later); colours come from the
 * theme variables, so light and dark both follow the theme. No lines
 * (DESIGN-ELEVATION.md): cards and rows are the group fill (.box), chips,
 * tracks and the segmented controls are fills, a selected segment is the
 * raised thumb; only focus rings draw an edge.
 */
.connector-card {
  position: relative;
  display: flex;
  gap: 1rem;
  align-items: flex-start;
  min-width: 0;
}
/* The card is an a.box: the global .box gives it the hover and pressed
   fills. Cards never float, so no hover shadow. */
.connector-card:hover,
.connector-card:active {
  box-shadow: none;
}
.connector-card:focus-visible,
.connector-row-link:focus-visible,
.connector-chip:focus-visible,
.connector-tabs button:focus-visible,
.connector-segmented button:focus-visible,
.connector-icon-button:focus-visible,
.connector-modal-close:focus-visible {
  outline: 2px solid var(--elev-focus-ring);
  outline-offset: 2px;
}
.connector-card-state {
  display: flex;
  flex-shrink: 0;
  align-items: center;
  justify-content: center;
  inline-size: 1.75rem;
  block-size: 1.75rem;
  border-radius: 0.5rem;
  background-color: var(--elev-fill-3);
}
.connector-icon,
.connector-icon-lg {
  background-color: #fff;
}
/* No icon: the avatar shows the name's initials (a <span>). On the white
   disc they were white on white in dark mode (1.08:1); they sit on the
   neutral control fill in the label colour instead. */
.connector-icon:has(> span),
.connector-icon-lg:has(> span) {
  background-color: var(--elev-fill-3);
  color: var(--color-content);
}
.connector-icon-lg {
  inline-size: 4rem;
  block-size: 4rem;
  font-size: 1.5rem;
}
.connector-row {
  position: relative;
  display: flex;
  gap: 0.75rem;
  align-items: center;
  justify-content: space-between;
  padding: 0.75rem;
}
/* A row is an li.box with a covering link: a fill step on hover, the
   pressed fill on press; no shadow (rows never float). */
.connector-row:hover {
  background-color: var(--elev-group-hover);
}
.connector-row:active {
  background-color: var(--elev-pressed);
}
.connector-row-link {
  position: absolute;
  inset: 0;
  border-radius: inherit;
}
.connector-note {
  display: flex;
  gap: 0.75rem;
  align-items: center;
  padding: 0.75rem;
  font-size: 0.875rem;
  border-radius: 0.5rem;
  background-color: var(--color-intermediate);
  color: var(--color-intermediate-content);
}
/* A warning is a red-tinted fill, not a stripe at the edge. */
.connector-note-warning {
  background-color: var(--elev-danger-fill);
  color: var(--color-content);
}
.connector-note-warning > .ti {
  color: var(--color-failure);
}
.connector-warning {
  display: flex;
  gap: 0.5rem;
  align-items: flex-start;
  margin-block-start: 0.5rem;
  font-size: 0.8125rem;
  color: var(--color-failure);
}
.connector-tabs {
  display: inline-flex;
  gap: 0.25rem;
  padding: 0.25rem;
  border-radius: 0.75rem;
  background-color: var(--elev-fill-3);
}
.connector-tabs button {
  padding-block: 0.375rem;
  padding-inline: 0.875rem;
  border-radius: 0.5rem;
  font-size: 0.875rem;
  color: var(--color-content-dimmed);
  transition: color 0.15s ease, background-color 0.15s ease;
}
.connector-tabs button:hover {
  color: var(--color-content);
}
/* Touch: the control is 44px tall (36px segments on a 4px track). */
@media (pointer: coarse) {
  .connector-tabs button {
    min-block-size: 2.25rem;
  }
}
/* The selected tab is the thumb colour, a surface step on the track. */
.connector-tabs button[aria-selected="true"] {
  background-color: var(--elev-thumb);
  color: var(--color-content);
  box-shadow: var(--elev-shadow-1);
}
.connector-search {
  position: relative;
  display: flex;
  align-items: center;
  min-inline-size: 14rem;
}
.connector-search > i {
  position: absolute;
  inset-inline-start: 0.75rem;
  pointer-events: none;
}
.connector-search > input {
  padding-inline-start: 2.25rem;
}
.connector-chip {
  display: inline-flex;
  gap: 0.5rem;
  align-items: center;
  padding-block: 0.375rem;
  padding-inline: 0.75rem;
  font-size: 0.875rem;
  border-radius: 0.5rem;
  background-color: var(--elev-fill-3);
  transition: background-color 0.15s ease;
}
.connector-chip:hover {
  background-color: var(--elev-fill-2);
}
.connector-chip:active {
  background-color: var(--elev-fill-1);
  transition: none;
}
.connector-tool-chip {
  display: inline-block;
  max-inline-size: 100%;
  padding-block: 0.375rem;
  padding-inline: 0.75rem;
  overflow: hidden;
  font-size: 0.8125rem;
  text-overflow: ellipsis;
  white-space: nowrap;
  border-radius: 0.5rem;
  background-color: var(--elev-fill-3);
}
.connector-icon-button,
.connector-modal-close {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  inline-size: 2rem;
  block-size: 2rem;
  border-radius: 9999px;
  color: var(--color-content-dimmed);
}
/* 32px to look at, 44px to hit (like .button-icon.button-sm). */
.connector-icon-button::before,
.connector-modal-close::before {
  content: "";
  position: absolute;
  inset: -6px;
}
/* Icon-only buttons (the "more" menu, a modal's close) are gray discs:
   fill-3, fill-2 on hover, fill-1 the instant they are pressed. */
.connector-icon-button,
.connector-modal-close {
  background-color: var(--elev-fill-3);
  transition: background-color 0.15s ease, color 0.15s ease;
}
.connector-icon-button:hover,
.connector-modal-close:hover {
  background-color: var(--elev-fill-2);
  color: var(--color-content);
}
.connector-icon-button:active,
.connector-modal-close:active {
  background-color: var(--elev-fill-1);
  transition: none;
}
.connector-switch {
  position: relative;
  display: block;
  flex-shrink: 0;
  inline-size: 2.5rem;
  block-size: 1.5rem;
  border-radius: 1.5rem;
  background-color: var(--elev-fill-1);
  transition: background-color 0.15s ease;
}
.connector-switch::after {
  content: "";
  position: absolute;
  inset-block-start: 0.125rem;
  inset-inline-start: 0.125rem;
  inline-size: 1.25rem;
  block-size: 1.25rem;
  border-radius: 9999px;
  background-color: #fff;
  box-shadow: var(--elev-shadow-1);
  transition: inset-inline-start 0.15s ease;
}
.peer:checked + .connector-switch {
  background-color: var(--color-success);
}
.peer:checked + .connector-switch::after {
  inset-inline-start: 1.125rem;
}
.peer:focus-visible + .connector-switch {
  outline: 2px solid var(--elev-focus-ring);
  outline-offset: 2px;
}
.connector-segmented {
  display: flex;
  flex-shrink: 0;
  gap: 0.125rem;
  padding: 0.125rem;
  border-radius: 0.5rem;
  background-color: var(--elev-fill-3);
}
.connector-segmented button {
  display: flex;
  align-items: center;
  justify-content: center;
  inline-size: 2rem;
  block-size: 1.75rem;
  font-size: 1.125rem;
  border-radius: 0.375rem;
  color: var(--color-content-dimmed);
}
.connector-segmented button:hover {
  color: var(--color-content);
}
/* Touch: 44px-wide segments with a 44px-tall hit area (the tool row wraps
   the control under the tool's name on a narrow card, connection.twig). */
@media (pointer: coarse) {
  .connector-segmented button {
    position: relative;
    inline-size: 2.75rem;
    block-size: 2.25rem;
  }
  .connector-segmented button::before {
    content: "";
    position: absolute;
    inset-block: -0.25rem;
    inset-inline: 0;
  }
}
.connector-segmented button.is-active {
  background-color: var(--elev-thumb);
  color: var(--color-content);
  box-shadow: var(--elev-shadow-1);
}
.connector-segmented button.is-allow {
  color: var(--color-success);
}
.connector-segmented button.is-deny {
  color: var(--color-failure);
}
.connector-catalogue-item.is-imported {
  opacity: 0.6;
}
.connector-badge-warning {
  color: var(--color-failure);
}
@media (prefers-reduced-motion: reduce) {
  .connector-tabs button,
  .connector-chip,
  .connector-switch,
  .connector-switch::after {
    transition: none;
  }
}

/* Connector approval card in chat (F4): a group-fill card. The card takes
   focus itself (so Esc denies), and shows it with the focus ring. */
.connector-approval {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  margin-block: 0.5rem;
  padding: 0.875rem;
  /* [Doona] - No lines (chat area): a group fill marks the card, no rim.
     The card takes focus on mount (tabindex=-1); a keyboard user sees the
     focus ring, a mouse user sees no edge appear. */
  border-radius: 1rem;
  background-color: var(--elev-group);
}
/* The card is only ever focused by script (tabindex=-1, Tab never lands
   on it), right after the message that asked for approval, which was often
   sent with Enter, so the browser drew the keyboard ring around the whole
   card. Its buttons carry their own focus ring; the card itself marks focus
   with one fill step (group → group-hover), no edge. */
.connector-approval:focus,
.connector-approval:focus-visible {
  outline: none;
}

.connector-approval:focus-visible {
  background-color: var(--elev-group-hover);
}
.connector-approval[data-state="resolved"] {
  opacity: 0.75;
}
.connector-approval-head {
  display: flex;
  gap: 0.625rem;
  align-items: flex-start;
}
.connector-approval-head > .ti {
  font-size: 1.25rem;
  color: var(--color-content-dimmed);
}
.connector-approval-write {
  margin-inline-start: 0.375rem;
  font-size: 0.75rem;
  color: var(--color-failure);
}
/* Light: the brand red is 2.83:1 on the card's group fill; a deeper shade
   of it reads (AA). Dark keeps the red, which passes there. */
html[data-mode="light"] .connector-approval-write {
  color: color-mix(in oklab, var(--color-failure) 62%, black);
}
.connector-approval-args {
  max-block-size: 10rem;
  margin: 0;
  padding: 0.625rem;
  overflow: auto;
  font-size: 0.75rem;
  line-height: 1.5;
  white-space: pre-wrap;
  word-break: break-word;
  text-align: start;
  border-radius: 0.625rem;
  background-color: var(--elev-fill-4);
}
.connector-approval-args.is-open {
  max-block-size: 24rem;
}
.connector-approval-args:focus-visible {
  outline: 2px solid var(--elev-focus-ring);
  outline-offset: 2px;
}
.connector-approval-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

/*
 * Message parts P1: the clarifying-questions card on an assistant message
 * (.dn-questions) and the answers on the user message that carries them
 * (.dn-answers). Markup: resources/views/snippets/cards/questions.twig.
 *
 * Logical properties only (RTL today, LTR later); colours come from the
 * theme variables, so light and dark both follow css-variables.twig. The
 * selected state is never colour alone: the tick icon changes too, and the
 * native radio/checkbox underneath carries it for assistive technology.
 */

/* [Doona:START] - Message parts P1: clarifying questions */
.dn-questions__card {
  display: flex;
  flex-direction: column;
  gap: 16px;
  margin-block: 4px;
  padding-block: 16px;
  padding-inline: 16px;
  /* [Doona] - No lines: a group fill marks the card, no rim. */
  border-radius: 16px;
  background: var(--elev-group);
}

.dn-questions__head {
  display: flex;
  align-items: flex-start;
  gap: 10px;
}

.dn-questions__icon {
  flex-shrink: 0;
  margin-block-start: 2px;
  font-size: 1.25rem;
  color: var(--color-content-dimmed);
}

.dn-questions__titles {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-inline-size: 0;
  flex-grow: 1;
}

.dn-questions__title {
  margin: 0;
  font-size: 0.9375rem;
  font-weight: 700;
  color: var(--color-content);
}

.dn-questions__subtitle {
  margin: 0;
  font-size: 0.8125rem;
  line-height: 1.6;
  color: var(--color-content-dimmed);
}

.dn-questions__close {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  inline-size: 32px;
  block-size: 32px;
  border-radius: 9999px;
  color: var(--color-content-dimmed);
  transition: background-color 0.15s ease, color 0.15s ease;
}

.dn-questions__close:hover {
  background: var(--elev-hover);
  color: var(--color-content);
}

.dn-questions__close:active {
  background: var(--elev-pressed);
}

/* 44px to touch around the 32px mark. */
.dn-questions__close {
  position: relative;
}

.dn-questions__close::before {
  content: "";
  position: absolute;
  inset: -6px;
}

.dn-questions__q {
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-inline-size: 0;
  margin: 0;
  padding: 0;
  border: 0;
}

.dn-questions__legend {
  padding: 0;
  margin-block-end: 8px;
  font-size: 0.875rem;
  font-weight: 600;
  line-height: 1.7;
  color: var(--color-content);
}

.dn-questions__hint {
  margin-inline-start: 4px;
  font-size: 0.75rem;
  font-weight: 400;
  color: var(--color-content-dimmed);
}

.dn-questions__options {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

/* The whole chip is the hit target; the input stays in the accessibility
   tree and keyboard order, visually hidden. */
.dn-questions__option {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  max-inline-size: 100%;
  min-block-size: 36px;
  padding-block: 6px;
  padding-inline: 12px;
  /* [Doona] - A filled chip (fill-3), not an outlined one. Selected is the
     accent tint plus the tick icon, so it never relies on colour alone. */
  border-radius: 9999px;
  background: var(--elev-fill-3);
  color: var(--color-content);
  font-size: 0.8125rem;
  font-weight: 500;
  line-height: 1.5;
  cursor: pointer;
  user-select: none;
  transition: background-color 0.15s ease, transform 0.1s ease;
}

.dn-questions__option:hover {
  background: var(--elev-fill-2);
}

.dn-questions__option:active {
  background: var(--elev-fill-1);
  transform: scale(0.98);
}

.dn-questions__option.is-selected,
.dn-questions__option.is-selected:hover {
  background: color-mix(in srgb, var(--color-accent) 22%, transparent);
}

/* Touch: 44px options (was 36px). */
@media (pointer: coarse) {
  .dn-questions__option {
    min-block-size: 44px;
  }
}

.dn-questions__option.is-locked {
  opacity: 0.5;
  cursor: not-allowed;
}

.dn-questions__option:has(.dn-questions__input:focus-visible) {
  outline: 2px solid var(--elev-focus-ring);
  outline-offset: 2px;
}

.dn-questions__input {
  position: absolute;
  inline-size: 1px;
  block-size: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.dn-questions__tick {
  flex-shrink: 0;
  font-size: 0.9375rem;
  color: var(--color-content-dimmed);
}

.dn-questions__option.is-selected .dn-questions__tick {
  color: var(--color-content);
}

.dn-questions__other {
  inline-size: 100%;
  min-block-size: 38px;
  padding-block: 8px;
  padding-inline: 12px;
  /* [Doona] - A filled field like .input: fill-3, hover fill-2, focus =
     the page surface + the focus ring. */
  border: 0;
  border-radius: 12px;
  background: var(--elev-fill-3);
  color: var(--color-content);
  font-size: 0.8125rem;
  transition: background-color 0.15s ease;
}

.dn-questions__other:hover {
  background: var(--elev-fill-2);
}

.dn-questions__other:focus {
  background: var(--elev-bg);
}

.dn-questions__other::placeholder {
  color: var(--color-content-dimmed);
}

.dn-questions__other:focus-visible {
  outline: 2px solid var(--elev-focus-ring);
  outline-offset: 1px;
}

.dn-questions__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
}

/* Plain buttons (DESIGN-ELEVATION §0.1): tint-coloured text, no fill, no
   underline; dim on press like iOS. They were grey underlined text, which
   read as a link and not as the card's second action. 44px tall to touch. */
.dn-questions__skip,
.dn-questions__link {
  position: relative;
  padding-inline: 8px;
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--elev-tint-text);
  transition: opacity 0.15s ease;
}

.dn-questions__skip::before,
.dn-questions__link::before {
  content: "";
  position: absolute;
  inset: -12px -4px;
}

@media (hover: hover) {
  .dn-questions__skip:not(:disabled):hover,
  .dn-questions__link:not(:disabled):hover {
    opacity: 0.8;
  }
}

.dn-questions__skip:not(:disabled):active,
.dn-questions__link:not(:disabled):active {
  opacity: 0.55;
  transition-duration: 0ms;
}

.dn-questions__skip:disabled {
  opacity: 0.5;
}

/* «ارسال پاسخ‌ها» before anything is answered: the button's own disabled
   look (half-opacity grey) all but vanished. Disabled is a Gray button with
   a secondary label (AA), unmistakably present and unmistakably inactive. */
.dn-questions__actions .button:disabled {
  opacity: 1;
  background: var(--elev-fill-3);
  color: var(--color-content-dimmed);
}

.dn-questions__skip:focus-visible,
.dn-questions__link:focus-visible,
.dn-questions__close:focus-visible {
  outline: 2px solid var(--elev-focus-ring);
  outline-offset: 2px;
  border-radius: 6px;
}

.dn-questions__note {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  padding-block: 4px;
  font-size: 0.8125rem;
  color: var(--color-content-dimmed);
}

.dn-questions__note .ti {
  font-size: 1rem;
}

.dn-questions__note--muted {
  font-style: italic;
}

/* ---- Answers on the user message ------------------------------------- */
.dn-answers__list {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.dn-answers__row {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.dn-answers__question {
  font-size: 0.75rem;
  line-height: 1.6;
  color: var(--color-content-dimmed);
}

.dn-answers__chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.dn-answers__chip {
  display: inline-flex;
  align-items: center;
  max-inline-size: 100%;
  padding-block: 3px;
  padding-inline: 10px;
  border-radius: 9999px;
  background: color-mix(in srgb, var(--color-accent) 22%, transparent);
  color: var(--color-content);
  font-size: 0.8125rem;
  font-weight: 500;
  line-height: 1.6;
  overflow-wrap: anywhere;
}

.dn-answers__chip--skipped {
  background: var(--elev-fill-3);
  color: var(--color-content-dimmed);
  font-weight: 400;
}

.dn-answers__declined {
  margin: 0;
  font-size: 0.8125rem;
  font-style: italic;
  color: var(--color-content-dimmed);
}

@media (prefers-reduced-motion: reduce) {
  .dn-questions__option,
  .dn-questions__close {
    transition: none;
  }
}
/* [Doona:END] */

/*
 * Settings area (/app/settings/**, G12): the wider content column, the
 * settings title, the nav (lg and up: a sticky list beside the page), the
 * phone pattern (below lg: the settings index on /app/settings and a top bar
 * with a back button on every page), the shared page header, and the parts
 * every settings page is built from:
 *
 *   .settings-card            one level of card; never nested
 *   .settings-card-head       card title (h3) + one-line description,
 *                             optional actions at the end
 *   .settings-row             a list row: text at the start, a control at the
 *                             end; rows are told apart by space, never a line
 *   .settings-switch          on/off switch (input.peer + .settings-switch-track)
 *   .settings-fields          form field grid (two columns when there is room)
 *   .settings-card-foot       the card's save/submit bar
 *   .settings-card.is-danger  permanent, destructive actions
 *   .settings-identity        the profile card at the top of Profile
 *
 * Nav or index follows the viewport (lg, where the app itself switches
 * between the desktop shell and the mobile header and bottom nav); spacing
 * inside follows the width of the settings column (a container query), since
 * the history drawer can take 24rem of a wide screen.
 * Logical properties only, so the area mirrors for LTR locales. No lines
 * anywhere (DESIGN-ELEVATION.md): cards are the translucent group fill, the
 * nav column is surface-1, controls and states are fills, and only the
 * keyboard focus ring and error states draw an edge. Depth comes from the
 * elevation tokens (resources/assets/css/elevation.css), which follow the
 * mode themselves, so nothing here is written per mode except the brand
 * text colour on the phone top bar.
 * Replaces resources/assets/css/settings.css (Tailwind bundle).
 */

/* ---------- Content column ---------------------------------------------- */

#content > .container.doona-content-wide,
#content > .container.doona-content-wide > .max-w-4xl {
  max-width: 70rem;
}

/* The settings column is a size container (two columns or the pill strip
   follow its width). Older engines (Chrome < 129, Safari < 18.4, Firefox <
   133) give a size container layout containment, making it the containing
   block for position: fixed descendants, so no modal may live inside it:
   pages put theirs in the settings_modals block (layouts/settings.twig). */
.doona-settings {
  container: doona-settings / inline-size;
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
}

.doona-settings-top {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.5rem;
}

.doona-settings-top h1 {
  font-size: 1.5rem;
  line-height: 1.4;
}

.doona-settings-back,
.doona-settings-parent {
  display: inline-flex;
  align-self: flex-start;
  align-items: center;
  gap: 0.25rem;
  font-size: 0.8125rem;
  font-weight: 500;
  color: var(--color-content-dimmed);
  border-radius: 0.375rem;
  transition: color 0.15s ease;
}

.doona-settings-back:hover,
.doona-settings-parent:hover {
  color: var(--color-content);
}

.doona-settings-back:focus-visible,
.doona-settings-parent:focus-visible {
  outline: 2px solid var(--elev-focus-ring);
  outline-offset: 2px;
}

.doona-settings-body {
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
}

.doona-settings-page {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  min-width: 0;
}

/* ---------- Page header -------------------------------------------------- */

.doona-settings-header {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem 1rem;
  margin-block-end: 0.5rem;
}

.doona-settings-header-text {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.25rem;
  min-width: 0;
}

.doona-settings-header h2 {
  font-size: 1.25rem;
  line-height: 1.5;
}

.doona-settings-header p {
  font-size: 0.875rem;
  line-height: 1.7;
  color: var(--color-content-dimmed);
}

.doona-settings-parent {
  margin-block-end: 0.25rem;
}

/* ---------- Navigation (lg and up) -------------------------------------- */

/* Below lg there is no nav: the settings index takes its place (see "Phones"
   below). From lg up it is a sticky list on the inline-start side. */
.doona-settings-nav {
  display: none;
}

/* The nav column is a region beside the page: surface-1, told apart from
   the content by colour alone (no edge). */
.doona-settings-nav-list {
  display: flex;
  flex-direction: column;
  gap: 0.125rem;
  padding: 0.375rem;
  background-color: var(--elev-surface-1);
  border-radius: 1.25rem;
}

.doona-settings-nav-link {
  display: flex;
  align-items: center;
  gap: 0.625rem;
  height: 2.5rem;
  padding-inline: 0.75rem;
  font-size: 0.875rem;
  white-space: nowrap;
  color: var(--color-content-dimmed);
  border-radius: 0.75rem;
  transition: color 0.15s ease, background-color 0.15s ease;
}

.doona-settings-nav-link .settings-tile {
  width: 1.625rem;
  height: 1.625rem;
  font-size: 1rem;
  border-radius: 0.4375rem;
}

.doona-settings-nav-link:hover {
  color: var(--color-content);
  background-color: var(--elev-hover);
}

.doona-settings-nav-link:active {
  background-color: var(--elev-pressed);
  transition: none;
}

.doona-settings-nav-link:focus-visible {
  outline: 2px solid var(--elev-focus-ring);
  outline-offset: -2px;
}

/* Selected: in light a white pill on the gray column, in dark the neutral
   selected fill (higher = lighter). A surface step only, no shadow. */
.doona-settings-nav-link[aria-current='page'],
.doona-settings-nav-link[aria-current='page']:hover {
  font-weight: 600;
  color: var(--color-content);
  background-color: var(--elev-selected);
}

/* Light: a white pill on a near-white column only reads with shadow-1
   ("raised selected", DESIGN-ELEVATION.md §1.3). */
html[data-mode='light'] .doona-settings-nav-link[aria-current='page'] {
  background-color: var(--elev-surface-2);
  box-shadow: var(--elev-shadow-1);
}

@media (min-width: 1024px) {
  .doona-settings-body {
    display: grid;
    grid-template-columns: 12.5rem minmax(0, 1fr);
    gap: 1.5rem;
    align-items: start;
  }

  .doona-settings-nav {
    display: block;
    position: sticky;
    top: 2.5rem;
  }

  /* The page header lines up with the first nav entry. */
  .doona-settings-header {
    min-height: 2.5rem;
  }
}

/* A roomier nav column once the settings column can afford it (a wide
   screen without the history drawer). */
@container doona-settings (width >= 50rem) {
  .doona-settings-body {
    grid-template-columns: 14rem minmax(0, 1fr);
    gap: 2.5rem;
  }
}

/* ---------- Icon tiles ---------------------------------------------------- */

/* A rounded square in one colour with a white glyph, as in iOS Settings:
   on the index rows, the desktop nav and rows inside the pages. One hue
   per page (layouts/settings.twig `tile`). */
.settings-tile {
  --tile: #8e8e93;
  display: inline-flex;
  flex-shrink: 0;
  align-items: center;
  justify-content: center;
  width: 1.875rem;
  height: 1.875rem;
  font-size: 1.125rem;
  color: #fff;
  background-color: var(--tile);
  border-radius: 0.5rem;
}

.settings-tile[data-tile='orange'] { --tile: #f58a06; }
.settings-tile[data-tile='indigo'] { --tile: #5e5ce6; }
.settings-tile[data-tile='green'] { --tile: #2fb457; }
.settings-tile[data-tile='blue'] { --tile: #0a84ff; }
.settings-tile[data-tile='pink'] { --tile: #ff375f; }
.settings-tile[data-tile='purple'] { --tile: #af52de; }
.settings-tile[data-tile='red'] { --tile: #ff3b30; }
.settings-tile[data-tile='slate'] { --tile: #7c7c84; }

/* ---------- Phones and tablets (below lg) ------------------------------- */

/* The settings index on /app/settings; desktop shows the profile there. */
.settings-index {
  display: flex;
  flex-direction: column;
  gap: 1.75rem;
}

/* The top bar of a page; from lg up the page header and nav do its job. */
.settings-topbar {
  display: none;
}

@media (min-width: 1024px) {
  .settings-index {
    display: none;
  }
}

@media (max-width: 1023.98px) {
  /* The index has a large title; a page has its top bar instead. Persian
     is never letter-spaced: tracking breaks the joins of a cursive script. */
  .doona-settings-top .doona-settings-back,
  .doona-settings.is-page .doona-settings-top {
    display: none;
  }

  .doona-settings-top h1 {
    font-size: 1.875rem;
    font-weight: 800;
    line-height: 1.3;
  }

  .doona-settings.is-home .doona-settings-body {
    display: none;
  }

  .doona-settings.is-page {
    gap: 0;
  }

  /* Sticky translucent bar, edge to edge: the back button (chevron and
     where it goes) at the start, the title centred. Content scrolls under
     a soft fade instead of a hard line. */
  .settings-topbar {
    position: sticky;
    top: 0;
    z-index: 60;
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
    align-items: center;
    min-height: 3rem;
    margin-inline: -1rem;
    margin-block: -1rem 0.25rem;
    padding-inline: 0.25rem;
    background-color: var(--color-main);
  }

  /* Translucent where the engine can mix the theme colour (an unsupported
     color-mix() with var() would otherwise leave the bar transparent). */
  @supports (background-color: color-mix(in srgb, red 50%, transparent)) {
    .settings-topbar {
      background-color: color-mix(in srgb, var(--color-main) 72%, transparent);
      -webkit-backdrop-filter: blur(20px) saturate(180%);
      backdrop-filter: blur(20px) saturate(180%);
    }

    .settings-topbar::after {
      content: '';
      position: absolute;
      inset-inline: 0;
      inset-block-start: 100%;
      height: 0.75rem;
      background: linear-gradient(to bottom, color-mix(in srgb, var(--color-main) 72%, transparent), transparent);
      pointer-events: none;
    }
  }

  .settings-topbar-back {
    display: inline-flex;
    align-items: center;
    justify-self: start;
    gap: 0.125rem;
    max-width: 100%;
    min-height: 2.75rem;
    padding-inline: 0.5rem 0.75rem;
    font-size: 0.9375rem;
    color: var(--color-gradient-from);
    border-radius: 0.75rem;
  }

  .settings-topbar-back .ti {
    flex-shrink: 0;
    font-size: 1.5rem;
  }

  .settings-topbar-back span {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  /* The brand orange is too light for text on the light bar (2.4:1). */
  html[data-mode='light'] .settings-topbar-back {
    color: #a85a00;
  }

  /* Pressed: the iOS nav bar dim, done as a colour change. Opacity or a
     transform would put the label on its own layer inside the
     backdrop-filtered bar, which WebKit rasterises soft. */
  .settings-topbar-back:active {
    color: rgb(245 138 6 / 0.45);
  }

  html[data-mode='light'] .settings-topbar-back:active {
    color: rgb(168 90 0 / 0.45);
  }

  .settings-topbar-back:focus-visible {
    outline: 2px solid var(--elev-focus-ring);
    outline-offset: -2px;
  }

  .settings-topbar-title {
    grid-column: 2;
    max-width: 55vw;
    overflow: hidden;
    font-size: 1rem;
    font-weight: 700;
    line-height: 1.5;
    text-align: center;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  /* Under the bar: the page description and actions; the title is in the
     bar, and the bar's back button replaces the parent link. */
  .doona-settings-header h2,
  .doona-settings-header .doona-settings-parent,
  .doona-settings-page > .doona-settings-parent {
    display: none;
  }

  .doona-settings-header {
    margin-block: 0.25rem 0.5rem;
  }

  .doona-settings-header:not(:has(p, .button)) {
    display: none;
  }

  .doona-settings-header p {
    padding-inline: 0.25rem;
    font-size: 0.8125rem;
    line-height: 1.9;
  }

  .doona-settings-page {
    gap: 1rem;
  }
}

@media (min-width: 768px) and (max-width: 1023.98px) {
  .settings-topbar {
    margin-inline: -1.5rem;
    padding-inline: 0.75rem;
  }
}

@media (max-width: 1023.98px) and (prefers-reduced-transparency: reduce) {
  .settings-topbar {
    background-color: var(--color-main) !important;
    -webkit-backdrop-filter: none !important;
    backdrop-filter: none !important;
  }

  .settings-topbar::after {
    content: none !important;
  }
}

/* Account card at the top of the index: the group fill, no rim and no
   decorative wash (DESIGN-ELEVATION §0.1: no ornamental gradients). */
.settings-index-account {
  display: flex;
  align-items: center;
  gap: 0.875rem;
  min-height: 5rem;
  padding: 0.875rem 1rem;
  background-color: var(--elev-group);
  border-radius: 1.25rem;
  -webkit-tap-highlight-color: transparent;
}

.settings-index-avatar {
  width: 3.75rem;
  height: 3.75rem;
  font-size: 1.125rem;
}

.settings-index-account-text {
  display: flex;
  flex: 1 1 0;
  flex-direction: column;
  gap: 0.125rem;
  min-width: 0;
}

.settings-index-account-name {
  overflow: hidden;
  font-size: 1.125rem;
  font-weight: 700;
  line-height: 1.5;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.settings-index-account-phone {
  align-self: flex-start;
  font-size: 0.875rem;
  color: var(--color-content-dimmed);
}

.settings-index-account > .ti,
.settings-index-chevron {
  flex-shrink: 0;
  font-size: 1.125rem;
  color: var(--color-content-muted);
}

/* A group: a caption over an inset grouped list of rows (the spec's
   .list-grouped: one rounded group fill, rows 2px apart, a row fills on
   hover and press). No hairlines between rows: the row height and the
   icon tiles keep them apart. */
.settings-index-group {
  display: flex;
  flex-direction: column;
  gap: 0.375rem;
}

.settings-index-label {
  padding-inline: 1rem;
  font-size: 0.8125rem;
  font-weight: 500;
  color: var(--color-content-dimmed);
}

.settings-index-list {
  display: flex;
  flex-direction: column;
  gap: 0;
  padding: 0.25rem;
  background-color: var(--elev-group);
  border-radius: 1.25rem;
}

.settings-index-row {
  position: relative;
  display: flex;
  align-items: center;
  gap: 0.875rem;
  min-height: 3.25rem;
  padding-block: 0.5rem;
  padding-inline: 0.75rem 0.625rem;
  border-radius: 1rem;
  transition: background-color 0.15s ease;
  -webkit-tap-highlight-color: transparent;
}

/* [Doona] - Owner decision: an iOS inset hairline between index rows,
   starting past the icon tile. */
.settings-index-list > li + li > .settings-index-row::before {
  content: '';
  position: absolute;
  inset-block-start: 0;
  inset-inline: 3.5rem 0.75rem;
  border-block-start: 1px solid var(--elev-separator);
  pointer-events: none;
}

/* Hover only where there is a pointer (a tap would leave it stuck). */
@media (hover: hover) {
  .settings-index-row:hover {
    background-color: var(--elev-hover);
  }

  .settings-index-account:hover {
    background-color: var(--elev-group-hover);
  }
}

/* Feedback the moment a finger lands, not on release: a fill only,
   instantly. A scale would resample the text and blur it. */
.settings-index-row:active,
.settings-index-account:active {
  background-color: var(--elev-pressed);
  transition: none;
}

.settings-index-row:focus-visible,
.settings-index-account:focus-visible {
  outline: 2px solid var(--elev-focus-ring);
  outline-offset: -2px;
}

.settings-index-title {
  flex: 1 1 0;
  min-width: 0;
  font-size: 0.9375rem;
  font-weight: 500;
  line-height: 1.6;
}

.settings-index-value {
  flex-shrink: 0;
  font-size: 0.875rem;
  color: var(--color-content-dimmed);
}

/* ---------- Page transitions (phones) ---------------------------------- */

/* Between two settings pages Turbo runs a view transition (the meta in
   layouts/settings.twig). On phones the page slides in from the inline
   end and the previous one drifts back toward the start; going back
   (the top bar's back button sets data-settings-nav, the browser's back
   sets Turbo's data-turbo-visit-direction) runs the same path in reverse.
   The top bar, mobile header and bottom nav swap in place without
   animating. Turbo skips the transition under prefers-reduced-motion;
   from lg up there is no animation at all. */
:root {
  --settings-vt-dir: 1;
}

:root[dir='rtl'] {
  --settings-vt-dir: -1;
}

/* The scrolling #content is what slides: it is screen sized and clips its
   own content, so the page neither paints over the mobile header and
   bottom nav nor swoops in from its scroll position, and its background
   hides the outgoing page. The header and bottom nav are named so they
   stay put above it. */
@media (max-width: 1023.98px) {
  html:has(.doona-settings) #content {
    view-transition-name: settings-pane;
    background-color: var(--color-main);
  }

  html:has(.doona-settings) .settings-topbar {
    view-transition-name: settings-topbar;
  }

  html:has(.doona-settings) .doona-mobile-header {
    view-transition-name: settings-mobile-header;
  }

  html:has(.doona-settings) .bottom-nav {
    view-transition-name: settings-bottom-nav;
  }
}

@keyframes settings-pane-in-forward {
  from { transform: translateX(calc(var(--settings-vt-dir) * 100%)); }
}

@keyframes settings-pane-out-forward {
  to { transform: translateX(calc(var(--settings-vt-dir) * -30%)); opacity: 0.4; }
}

@keyframes settings-pane-in-back {
  from { transform: translateX(calc(var(--settings-vt-dir) * -30%)); opacity: 0.4; }
}

@keyframes settings-pane-out-back {
  to { transform: translateX(calc(var(--settings-vt-dir) * 100%)); }
}

::view-transition-old(settings-pane) {
  animation: 0.32s cubic-bezier(0.32, 0.72, 0, 1) both settings-pane-out-forward;
}

::view-transition-new(settings-pane) {
  animation: 0.32s cubic-bezier(0.32, 0.72, 0, 1) both settings-pane-in-forward;
}

html[data-turbo-visit-direction='back']::view-transition-old(settings-pane),
html[data-settings-nav='back']::view-transition-old(settings-pane) {
  z-index: 1;
  animation-name: settings-pane-out-back;
}

html[data-turbo-visit-direction='back']::view-transition-new(settings-pane),
html[data-settings-nav='back']::view-transition-new(settings-pane) {
  animation-name: settings-pane-in-back;
}

::view-transition-group(settings-pane) {
  animation-duration: 0.32s;
}

/* The top bar does not take part in the motion: its outgoing snapshot is
   dropped and the incoming one is shown as is, so its text is never
   faded, scaled or resampled mid-transition. */
::view-transition-group(settings-topbar),
::view-transition-new(settings-topbar),
::view-transition-group(settings-mobile-header),
::view-transition-new(settings-mobile-header),
::view-transition-group(settings-bottom-nav),
::view-transition-new(settings-bottom-nav) {
  animation: none;
}

/* The mobile header and bottom nav are the same on both pages: show the
   new one as is rather than cross-fading two copies of their text. */
::view-transition-old(settings-mobile-header),
::view-transition-old(settings-bottom-nav) {
  display: none;
}

/* Engines carry the bar's backdrop-filter over to its transition group,
   where it keeps blurring whatever slides underneath for the length of the
   transition, even with no snapshot in it: a soft smear where the bar was
   (what read as a blurry back button). The snapshot already holds the bar's
   own background, so the group needs no filter. */
::view-transition-group(settings-topbar) {
  -webkit-backdrop-filter: none !important;
  backdrop-filter: none !important;
}

::view-transition-old(settings-topbar) {
  display: none;
}

/* A browser back that already animated (the iOS edge swipe): no second
   slide (the top bar's back button sets this on popstate). */
html[data-settings-no-slide]::view-transition-old(settings-pane),
html[data-settings-no-slide]::view-transition-new(settings-pane) {
  animation: none;
}

@media (min-width: 1024px) {
  html:has(.doona-settings)::view-transition-group(*),
  html:has(.doona-settings)::view-transition-old(*),
  html:has(.doona-settings)::view-transition-new(*) {
    animation: none !important;
  }
}

/* Turbo already skips view transitions under reduced motion; should one
   run anyway, it is a plain cross-fade. */
@keyframes settings-pane-fade-in {
  from { opacity: 0; }
}

@keyframes settings-pane-fade-out {
  to { opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  html::view-transition-old(settings-pane) {
    animation-name: settings-pane-fade-out !important;
  }

  html::view-transition-new(settings-pane) {
    animation-name: settings-pane-fade-in !important;
  }
}

/* ---------- Cards --------------------------------------------------------- */

/* Only surface and spacing: no display or flex-direction, so a card that
   lays itself out with utilities (flex, sm:flex-row…) keeps doing so; this
   module is unlayered and would otherwise beat them. The surface is the
   translucent group fill (the global .box), with no rim. */
.settings-card {
  min-width: 0;
  padding: 1.25rem;
  background-color: var(--elev-group);
  border-radius: 1.25rem;
}

@container doona-settings (width >= 36rem) {
  .settings-card {
    padding: 1.5rem;
  }
}

/* Anything still built from .box inside the settings column (the connector
   cards and rows, empty states) gets a radius on the same scale instead of
   the global 32px. Radius only: padding stays with the markup's utilities. */
.doona-settings .box {
  border-radius: 1rem;
}

/* A card holding an empty state. */
.settings-card.settings-card-empty {
  padding-block: 3rem;
}

.settings-card-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
  margin-block-end: 1.25rem;
}

.settings-card-head:last-child {
  margin-block-end: 0;
}

.settings-card-head h3 {
  font-size: 1rem;
  line-height: 1.6;
}

.settings-card-head p,
.settings-row-desc,
.settings-hint {
  font-size: 0.8125rem;
  line-height: 1.8;
  color: var(--color-content-dimmed);
}

.settings-card-head p {
  margin-block-start: 0.125rem;
}

.settings-card-foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  gap: 0.75rem;
  margin-block-start: 1.75rem;
}

.settings-card-foot .button {
  width: 100%;
}

@container doona-settings (width >= 36rem) {
  .settings-card-foot .button {
    width: auto;
    min-width: 8rem;
  }
}

/* ---------- Rows ----------------------------------------------------------- */

/* Rows keep their own block padding; the list (or a lone row) pulls it back
   into the card padding, so the first and last rows sit flush. Nothing is
   drawn between rows: their padding is the separation. */
.settings-rows {
  display: flex;
  flex-direction: column;
  margin-block: -1rem;
}

.settings-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem 1.5rem;
  padding-block: 1rem;
}

.settings-card > .settings-row {
  margin-block: -1rem;
}

/* A head followed by rows: the first row's padding plus a little of the
   head's margin is the gap (no rule under the head). */
.settings-card-head + .settings-rows {
  margin-block-start: -0.5rem;
}

/* [Doona] - Owner decision: rows inside a card keep the iOS inset
   separator (lists read as one list, not loose lines). A hairline in the
   menu-separator token, inset past an icon tile, drawn inside a link row's
   hover inset so all separators line up. Cards and pages stay line-free. */
.settings-rows > .settings-row + .settings-row {
  border-block-start: 1px solid var(--elev-separator);
}

.settings-rows > .settings-row + .settings-row:where(:has(> .settings-tile:first-child, > .settings-row-lead > .settings-tile:first-child)) {
  border-block-start: 0;
  background-image: linear-gradient(var(--elev-separator), var(--elev-separator));
  background-repeat: no-repeat;
  background-position: right top;
  background-size: calc(100% - 2.75rem) 1px;
}

html[dir='rtl'] .settings-rows > .settings-row + .settings-row:where(:has(> .settings-tile:first-child, > .settings-row-lead > .settings-tile:first-child)) {
  background-position: left top;
}

.settings-rows > .settings-row + a.settings-row {
  border-block-start: 0;
  background-image: linear-gradient(var(--elev-separator), var(--elev-separator));
  background-position: center top;
  background-repeat: no-repeat;
  background-size: calc(100% - 1.5rem) 1px;
}

.settings-rows > .settings-row + a.settings-row:has(> .settings-tile:first-child) {
  background-position: right 0.75rem top;
  background-size: calc(100% - 4.25rem) 1px;
}

html[dir='rtl'] .settings-rows > .settings-row + a.settings-row:has(> .settings-tile:first-child) {
  background-position: left 0.75rem top;
}

.settings-row-text {
  display: flex;
  flex: 1 1 18rem;
  flex-direction: column;
  gap: 0.125rem;
  min-width: 0;
}

.settings-row-title {
  font-size: 0.875rem;
  font-weight: 600;
  line-height: 1.7;
  color: var(--color-content);
}

.settings-row-desc {
  max-width: 38rem;
}

.settings-row-action {
  display: flex;
  flex-shrink: 0;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
}

/* A row whose control (a switch, a menu button) never wraps under the text
   and sits level with the first line. Anything with flex-basis 100% (see
   .settings-row-extra) still drops to a line of its own. */
.settings-row.is-inline {
  align-items: flex-start;
}

.settings-row.is-inline > .settings-row-text,
.settings-row.is-inline > .settings-row-lead {
  flex: 1 1 0;
}

.settings-row.is-inline.is-center {
  align-items: center;
}

/* A row with a leading icon tile (.settings-tile). */
.settings-row-lead {
  display: flex;
  flex: 1 1 18rem;
  align-items: flex-start;
  gap: 0.875rem;
  min-width: 0;
}

.settings-row-lead.is-center {
  align-items: center;
}

/* A row that is itself a link to a sub-page. */
a.settings-row {
  flex-wrap: nowrap;
  column-gap: 0.875rem;
  margin-inline: -0.75rem;
  padding-inline: 0.75rem;
  border-radius: 0.75rem;
  transition: background-color 0.15s ease;
}

a.settings-row:hover {
  background-color: var(--elev-hover);
}

a.settings-row:active {
  background-color: var(--elev-pressed);
  transition: none;
}

a.settings-row:focus-visible {
  outline: 2px solid var(--elev-focus-ring);
  outline-offset: -2px;
}

a.settings-row > .ti {
  font-size: 1.125rem;
  color: var(--color-content-dimmed);
}

/* Whatever a row reveals under itself (the custom-instructions editor). */
.settings-row-extra {
  flex-basis: 100%;
}

/* The editor grows with its text instead of showing a resize grip (a
   desktop-only affordance that draws a corner mark on the field). Browsers
   without field-sizing keep the rows="4" height. */
.settings-row-extra textarea {
  min-block-size: 6.5rem;
  max-block-size: 20rem;
  resize: none;
  field-sizing: content;
}

/* ---------- Switch --------------------------------------------------------- */

.settings-switch {
  position: relative;
  display: inline-flex;
  flex-shrink: 0;
  align-items: center;
  cursor: pointer;
}

.settings-switch:has(input:disabled) {
  cursor: default;
}

/* Off: the strong control fill (fill-1), the iOS switch track. */
.settings-switch-track {
  position: relative;
  display: block;
  width: 2.5rem;
  height: 1.5rem;
  background-color: var(--elev-fill-1);
  border-radius: 9999px;
  transition: background-color 0.15s ease;
}

.settings-switch-track::after {
  content: '';
  position: absolute;
  inset-block-start: 0.125rem;
  inset-inline-start: 0.125rem;
  width: 1.25rem;
  height: 1.25rem;
  background-color: #fff;
  border-radius: 9999px;
  box-shadow: var(--elev-shadow-1);
  transition: inset-inline-start 0.15s ease;
}

.peer:checked + .settings-switch-track {
  background-color: var(--color-success);
}

.peer:checked + .settings-switch-track::after {
  inset-inline-start: 1.125rem;
}

.peer:focus-visible + .settings-switch-track {
  outline: 2px solid var(--elev-focus-ring);
  outline-offset: 2px;
}

.peer:disabled + .settings-switch-track {
  opacity: 0.5;
}

/* A locked switch that is off keeps its track at full strength (at half
   opacity the fill-1 track all but vanished on the card) and dims only the
   thumb, so it still reads as a switch, just not an active one. */
.peer:disabled:not(:checked) + .settings-switch-track {
  opacity: 1;
}

.peer:disabled:not(:checked) + .settings-switch-track::after {
  opacity: 0.55;
  box-shadow: none;
}

/* ---------- Fields --------------------------------------------------------- */

.settings-fields {
  display: grid;
  gap: 1.25rem;
}

.settings-fields label {
  display: flex;
  align-items: center;
  gap: 0.25rem;
  width: fit-content;
  margin-block-end: 0.5rem;
  font-size: 0.875rem;
  font-weight: 500;
}

@container doona-settings (width >= 36rem) {
  .settings-fields {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 1.25rem 1rem;
  }
}

/* A read-only value with a copy button (the invite link). */
.settings-copy-field {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
}

.settings-copy-value {
  display: flex;
  flex: 1 1 16rem;
  align-items: center;
  min-width: 0;
  height: 2.75rem;
  padding-inline: 0.875rem;
  font-size: 0.875rem;
  color: var(--color-content-dimmed);
  background-color: var(--elev-fill-3);
  border-radius: 0.75rem;
}

.settings-copy-value,
.settings-code {
  font-feature-settings: 'ss02' off;
}

.settings-copy-value > * {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.settings-copy-field .button {
  height: 2.75rem;
}

/* A small status line under a card body (the daily invite count). */
.settings-note {
  display: flex;
  align-items: flex-start;
  gap: 0.5rem;
  margin-block-start: 1rem;
  font-size: 0.8125rem;
  line-height: 1.8;
  color: var(--color-content-dimmed);
}

.settings-note > .ti {
  flex-shrink: 0;
  margin-block-start: 0.1875rem;
  font-size: 1rem;
}

.settings-note.is-failure {
  color: var(--color-failure);
}

/* ---------- Danger --------------------------------------------------------- */

/* Permanent, destructive actions: a red-tinted fill instead of the group
   fill, never a red rim. */
.settings-card.is-danger {
  background-color: var(--elev-danger-fill);
}

.settings-card.is-danger .settings-row-title {
  color: var(--elev-danger-text);
}


/* ---------- Profile identity ----------------------------------------------- */

.settings-identity {
  display: flex;
  align-items: center;
  gap: 1rem;
}

.settings-identity-text {
  display: flex;
  flex-direction: column;
  gap: 0.375rem;
  min-width: 0;
}

.settings-identity-text h3 {
  overflow: hidden;
  font-size: 1.125rem;
  line-height: 1.5;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.settings-identity-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem 1.25rem;
  font-size: 0.8125rem;
  color: var(--color-content-dimmed);
}

.settings-identity-meta > * {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
}

.settings-identity-meta .ti {
  font-size: 1rem;
}

@media (prefers-reduced-motion: reduce) {
  .settings-topbar-back,
  .settings-index-account,
  .settings-index-row,
  .doona-settings-nav-link,
  .doona-settings-back,
  .doona-settings-parent,
  a.settings-row,
  .settings-switch-track,
  .settings-switch-track::after {
    transition: none;
  }
}

/* ---------- Migration (extra/extensions/heyaikeedo/migration) ----------- */

/* Plain CSS here, not utilities: Tailwind does not scan extra/, so a
   utility only that template uses is never built. */

/* A progress track: the strong control fill, the bar on it in accent. */
.settings-progress {
  height: 0.25rem;
  overflow: hidden;
  background-color: var(--elev-fill-1);
  border-radius: 9999px;
}

/* The file drop zone: a quiet fill, not a dashed outline. It fills up on
   hover and the instant it is pressed. */
.settings-dropzone {
  cursor: pointer;
  background-color: var(--elev-fill-4);
  border-radius: 0.75rem;
  transition: background-color 0.15s ease;
}

.settings-dropzone:hover {
  background-color: var(--elev-fill-2);
}

.settings-dropzone:active {
  background-color: var(--elev-fill-1);
  transition: none;
}

@media (prefers-reduced-motion: reduce) {
  .settings-dropzone {
    transition: none;
  }
}

/* ---------- Field error ---------------------------------------------------- */

/* The message under a field that failed validation (a cleared name). */
.settings-field-error {
  display: flex;
  align-items: center;
  gap: 0.375rem;
  margin-block-start: 0.5rem;
  font-size: 0.8125rem;
  color: var(--elev-danger-text);
}

/* ---------- Choice list (radio rows) --------------------------------------- */

/* A single-choice list, iOS style (the memory audience): one grouped fill,
   every row is the radio itself, the chosen row carries a check at its
   end, and an inset hairline separates rows (owner decision, as on the
   settings index), starting past the avatar. */
.settings-choice-list {
  display: flex;
  flex-direction: column;
  padding: 0.25rem;
  background-color: var(--elev-group);
  border-radius: 1.25rem;
}

.settings-choice {
  position: relative;
  display: flex;
  align-items: center;
  gap: 0.875rem;
  width: 100%;
  min-height: 3.75rem;
  padding: 0.625rem 0.75rem;
  text-align: start;
  border-radius: 1rem;
  transition: background-color 0.15s ease;
  -webkit-tap-highlight-color: transparent;
}

.settings-choice ~ .settings-choice::before {
  content: '';
  position: absolute;
  inset-block-start: 0;
  inset-inline: 4.125rem 0.75rem;
  border-block-start: 1px solid var(--elev-separator);
  pointer-events: none;
}

@media (hover: hover) {
  .settings-choice:hover {
    background-color: var(--elev-hover);
  }
}

.settings-choice:active {
  background-color: var(--elev-pressed);
  transition: none;
}

.settings-choice:focus-visible {
  outline: 2px solid var(--elev-focus-ring);
  outline-offset: -2px;
}

/* While a choice saves, its row keeps full strength (the global
   button[processing] would fade it) and the spinner takes the check's place. */
.settings-choice[processing] {
  opacity: 1;
}

.settings-choice-text {
  display: flex;
  flex: 1 1 0;
  flex-direction: column;
  gap: 0.125rem;
  min-width: 0;
}

.settings-choice-title {
  font-size: 0.9375rem;
  font-weight: 600;
  line-height: 1.6;
}

.settings-choice-desc {
  font-size: 0.8125rem;
  line-height: 1.7;
  color: var(--color-content-dimmed);
}

/* The check (or the spinner while saving) at the row's end, in the tint
   colour, like a checked iOS list row. */
.settings-choice-mark {
  display: flex;
  flex-shrink: 0;
  align-items: center;
  justify-content: center;
  width: 1.5rem;
  height: 1.5rem;
  font-size: 1.25rem;
  color: var(--elev-tint-text);
}

.settings-choice-mark .spinner {
  width: 1.25rem;
  height: 1.25rem;
}

@media (prefers-reduced-motion: reduce) {
  .settings-choice {
    transition: none;
  }
}

/*
 * [Doona] - Admin: Latin fields inside the RTL admin.
 *
 * Keys, URLs, hosts, emails, hex colours and coupon codes are Latin by
 * nature, so their inputs carry dir="ltr" (a URL typed into an RTL field
 * reads «app/» for «/app»; a hex colour reads «F58A07#»). The field's own
 * padding then turns with it: `pe-11` (room for the show/hide or copy
 * glyph, which sits at the RTL end = the left) would pad the right, and
 * `ps-12` (room for the colour swatch at the RTL start = the right) would
 * pad the left. Swap them back to the side the glyph is on. In an LTR
 * locale there is no [dir=rtl] ancestor, so the utilities stand as they are.
 */
[dir='rtl'] input.input[dir='ltr'].pe-11 {
  padding-right: 0.75rem;
  padding-left: 2.75rem;
}

[dir='rtl'] input.input[dir='ltr'].ps-12 {
  padding-left: 0.75rem;
  padding-right: 3rem;
}

/* An empty LTR field (key, host, id) still shows its Persian placeholder in
   reading order; the value itself stays LTR. Same pattern as input.css. */
[dir='rtl'] input.input[dir='ltr']:placeholder-shown {
  direction: rtl;
  unicode-bidi: isolate;
}

/*
 * Message parts P4: the seed of a conversation opened from a Writer preset,
 * on the user message in the chat (snippets/cards/preset-seed.twig): the
 * preset and the answers the user gave, as a card. The template the model
 * reads is never sent to the browser.
 *
 * Logical properties only; colours from the theme variables; a group fill
 * with no rim (DESIGN-ELEVATION.md: no lines). The user
 * column is fit-content (pages/chat--user-message.css), so the card caps
 * its own width.
 */

/* [Doona:START] - Message parts P4: preset seed card */
.dn-preset-seed {
  display: flex;
  flex-direction: column;
  gap: 12px;
  inline-size: min(100%, 520px);
  padding-block: 14px;
  padding-inline: 16px;
  border-radius: 18px;
  border-start-start-radius: 6px;
  background: var(--elev-group);
}

.dn-preset-seed__head {
  display: flex;
  align-items: center;
  gap: 10px;
  min-inline-size: 0;
}

.dn-preset-seed__titles {
  display: flex;
  flex-direction: column;
  min-inline-size: 0;
}

.dn-preset-seed__eyebrow {
  font-size: 0.6875rem;
  font-weight: 600;
  color: var(--color-content-dimmed);
}

.dn-preset-seed__title {
  font-size: 0.9375rem;
  font-weight: 700;
  line-height: 1.6;
  color: var(--color-content);
  overflow-wrap: anywhere;
}

.dn-preset-seed__answers {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin: 0;
}

.dn-preset-seed__row {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-inline-size: 0;
}

.dn-preset-seed__label {
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--color-content-dimmed);
}

.dn-preset-seed__value {
  margin: 0;
  font-size: 0.875rem;
  line-height: 1.8;
  color: var(--color-content);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 5;
  overflow: hidden;
}

.dn-preset-seed__answers.is-open .dn-preset-seed__value {
  display: block;
  -webkit-line-clamp: unset;
  overflow: visible;
}

.dn-preset-seed__more {
  align-self: flex-start;
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--color-content-dimmed);
}

.dn-preset-seed__more:hover,
.dn-preset-seed__more:focus-visible {
  color: var(--color-content);
}

.dn-preset-seed__more:focus-visible {
  outline: 2px solid var(--elev-focus-ring);
  outline-offset: 2px;
  border-radius: 4px;
}

.dn-preset-seed__start {
  align-self: flex-start;
}
/* [Doona:END] */

/*
 * Message parts P4: the guided Writer — the wizard over a preset's fields
 * (templates/app/preset-wizard.twig, .dn-wizard) and the read-only view of a
 * classic Writer document (templates/app/document-view.twig, .dn-docview).
 *
 * Logical properties only (RTL today, LTR later); colours from the theme
 * variables and the elevation tokens, so light and dark both follow the
 * mode. No lines (DESIGN-ELEVATION.md): the card and the review list are
 * group fills, chips and the model button are control fills, the selected
 * chip is the solid button colour; only focus rings and the error state
 * draw an edge. A selected choice is never colour alone: its icon changes
 * too, and the native radio underneath carries the state for assistive
 * technology.
 */

/* [Doona:START] - Message parts P4: guided Writer */
.dn-wizard {
  display: flex;
  flex-direction: column;
  gap: 20px;
  inline-size: 100%;
  max-inline-size: 720px;
  margin-inline: auto;
  padding-block: 8px 48px;
}

.dn-wizard__crumb {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  align-self: flex-start;
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--color-content-dimmed);
  transition: color 0.15s ease;
}

.dn-wizard__crumb:hover,
.dn-wizard__crumb:focus-visible {
  color: var(--color-content);
}

.dn-wizard__crumb:focus-visible {
  outline: 2px solid var(--elev-focus-ring);
  outline-offset: 2px;
  border-radius: 4px;
}

.dn-wizard__head {
  display: flex;
  align-items: flex-start;
  gap: 14px;
}

.dn-wizard__avatar {
  flex-shrink: 0;
  inline-size: 48px;
  block-size: 48px;
  border-radius: 14px;
  font-size: 1.5rem;
}

.dn-wizard__titles {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-inline-size: 0;
}

.dn-wizard__title {
  margin: 0;
  font-size: 1.375rem;
  font-weight: 700;
  line-height: 1.5;
  color: var(--color-content);
  overflow-wrap: anywhere;
}

.dn-wizard__desc {
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 4px 8px;
  font-size: 0.875rem;
  line-height: 1.8;
  color: var(--color-content-dimmed);
}

.dn-wizard__card {
  display: flex;
  flex-direction: column;
  gap: 20px;
  padding-block: 20px;
  padding-inline: 20px;
  border-radius: 20px;
  background: var(--elev-group);
}

.dn-wizard__progress {
  display: flex;
  align-items: center;
  gap: 12px;
}

.dn-wizard__bar {
  position: relative;
  flex-grow: 1;
  block-size: 6px;
  border-radius: 9999px;
  background: var(--elev-fill-1);
  overflow: hidden;
}

.dn-wizard__bar-fill {
  position: absolute;
  inset-block: 0;
  inset-inline-start: 0;
  border-radius: inherit;
  background: var(--color-accent);
  transition: inline-size 0.25s ease;
}

.dn-wizard__count {
  flex-shrink: 0;
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--color-content-dimmed);
}

.dn-wizard__form {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.dn-wizard__step {
  display: flex;
  flex-direction: column;
  gap: 12px;
  min-inline-size: 0;
}

.dn-wizard__field {
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-inline-size: 0;
}

.dn-wizard__fieldset {
  margin: 0;
  padding: 0;
  border: 0;
}

.dn-wizard__label,
.dn-wizard__step-title {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 6px;
  margin: 0;
  padding: 0;
  font-size: 1rem;
  font-weight: 700;
  line-height: 1.7;
  color: var(--color-content);
}

.dn-wizard__step-title:focus {
  outline: none;
}

.dn-wizard__step-title:focus-visible {
  outline: 2px solid var(--elev-focus-ring);
  outline-offset: 4px;
  border-radius: 4px;
}

.dn-wizard__optional {
  font-size: 0.75rem;
  font-weight: 400;
  color: var(--color-content-dimmed);
}

.dn-wizard__info {
  margin: 0;
  font-size: 0.8125rem;
  line-height: 1.8;
  color: var(--color-content-dimmed);
}

.dn-wizard__input {
  inline-size: 100%;
}

.dn-wizard__textarea {
  min-block-size: 140px;
  resize: vertical;
  line-height: 1.8;
}

.dn-wizard__textarea-wrap {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.dn-wizard__keys {
  margin: 0;
  font-size: 0.75rem;
  color: var(--color-content-dimmed);
}

/* Touch screens have no Ctrl + Enter. */
@media (hover: none) {
  .dn-wizard__keys {
    display: none;
  }
}

.dn-wizard__chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

/* The whole chip is the hit target; the radio stays in the accessibility
   tree and keyboard order, visually hidden. */
.dn-wizard__chip {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  max-inline-size: 100%;
  min-block-size: 40px;
  padding-block: 8px;
  padding-inline: 14px;
  border-radius: 9999px;
  background: var(--elev-fill-3);
  color: var(--color-content);
  font-size: 0.875rem;
  font-weight: 500;
  line-height: 1.5;
  cursor: pointer;
  user-select: none;
  transition: background-color 0.15s ease, color 0.15s ease;
}

.dn-wizard__chip:hover {
  background: var(--elev-fill-2);
}

.dn-wizard__chip:active {
  background: var(--elev-fill-1);
  transition: none;
}

/* Chosen: the solid button colour, as the radio-button chips elsewhere. */
.dn-wizard__chip.is-selected,
.dn-wizard__chip.is-selected:hover {
  background: var(--color-button);
  color: var(--color-button-content);
}

.dn-wizard__chip:has(.dn-wizard__radio:focus-visible) {
  outline: 2px solid var(--elev-focus-ring);
  outline-offset: 2px;
}

.dn-wizard__radio {
  position: absolute;
  inline-size: 1px;
  block-size: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.dn-wizard__tick {
  flex-shrink: 0;
  font-size: 1rem;
  color: var(--color-content-dimmed);
}

.dn-wizard__chip.is-selected .dn-wizard__tick {
  color: inherit;
}

.dn-wizard__error {
  display: flex;
  align-items: flex-start;
  gap: 6px;
  margin: 0;
  font-size: 0.8125rem;
  line-height: 1.7;
  color: var(--color-failure);
}

.dn-wizard__error .ti {
  flex-shrink: 0;
  margin-block-start: 3px;
}

/* The review is a grouped list: one group fill (over the card's, so it
   reads one step up), rows 2px apart, no rules between them. */
.dn-wizard__review {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin: 0;
  padding: 4px;
  border-radius: 16px;
  background: var(--elev-group);
}

.dn-wizard__review-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-areas:
    "label edit"
    "value value";
  gap: 2px 12px;
  padding-block: 10px;
  padding-inline: 12px;
  border-radius: 12px;
}

.dn-wizard__review-label {
  grid-area: label;
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--color-content-dimmed);
}

.dn-wizard__review-value {
  grid-area: value;
  margin: 0;
  font-size: 0.875rem;
  line-height: 1.8;
  color: var(--color-content);
  overflow-wrap: anywhere;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 4;
  overflow: hidden;
}

/* The answer keeps its own line breaks; the template's indentation around
   it (between <dd> and the spans) must not. */
.dn-wizard__review-value > span {
  white-space: pre-wrap;
}

.dn-wizard__edit {
  grid-area: edit;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  min-block-size: 32px;
  padding-inline: 8px;
  border-radius: 8px;
  background: var(--elev-fill-3);
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--color-content);
  transition: background-color 0.15s ease, color 0.15s ease;
}

/* A small gray button: fill-3, fill-2 on hover, fill-1 on press. */
.dn-wizard__edit:hover,
.dn-wizard__edit:focus-visible {
  background: var(--elev-fill-2);
}

.dn-wizard__edit:active {
  background: var(--elev-fill-1);
  transition: none;
}

.dn-wizard__edit:focus-visible {
  outline: 2px solid var(--elev-focus-ring);
  outline-offset: 2px;
}

.dn-wizard__muted {
  color: var(--color-content-dimmed);
}

.dn-wizard__model-row {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.dn-wizard__model {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  inline-size: 100%;
  min-block-size: 48px;
  padding-block: 8px;
  padding-inline: 12px;
  border-radius: 14px;
  background: var(--elev-fill-3);
  color: var(--color-content);
  font-size: 0.875rem;
  font-weight: 600;
  text-align: start;
  transition: background-color 0.15s ease;
}

.dn-wizard__model:hover {
  background: var(--elev-fill-2);
}

.dn-wizard__model:active {
  background: var(--elev-fill-1);
  transition: none;
}

.dn-wizard__model:focus-visible {
  outline: 2px solid var(--elev-focus-ring);
  outline-offset: 2px;
}

.dn-wizard__model-name {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-inline-size: 0;
}

.dn-wizard__note {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  margin: 0;
  padding-block: 10px;
  padding-inline: 12px;
  border-radius: 12px;
  background: var(--elev-fill-4);
  font-size: 0.8125rem;
  line-height: 1.8;
  color: var(--color-content-dimmed);
}

.dn-wizard__note .ti {
  flex-shrink: 0;
  margin-block-start: 3px;
  font-size: 1rem;
}

.dn-wizard__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
}

.dn-wizard__primary {
  min-inline-size: 140px;
}

.dn-wizard__locked {
  align-items: flex-start;
}

.dn-wizard__locked-icon {
  font-size: 1.75rem;
  color: var(--color-content-dimmed);
}

/* Phones: the primary action spans the width and comes first. */
@media (max-width: 639px) {
  .dn-wizard__card {
    padding-inline: 16px;
    border-radius: 16px;
  }

  .dn-wizard__actions {
    flex-direction: column;
    align-items: stretch;
  }

  .dn-wizard__actions .button {
    inline-size: 100%;
    justify-content: center;
  }
}

@media (prefers-reduced-motion: reduce) {
  .dn-wizard__bar-fill,
  .dn-wizard__chip,
  .dn-wizard__edit,
  .dn-wizard__model {
    transition: none;
  }
}

/* Read-only classic Writer document */
.dn-docview__toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}

.dn-docview__content {
  overflow-wrap: anywhere;
}
/* [Doona:END] */

/*
 * Message parts P3: Canvas — the read-only document panel
 * (snippets/canvas.twig, #dn-canvas) and the cards canvas writes leave in the
 * chat (snippets/cards/artifact.twig, .dn-artifact).
 *
 * Desktop (>= 64rem): the panel is fixed at the inline end (the left in RTL)
 * and html[data-canvas="open"] gives #content an inline-end margin of the
 * panel's width (--dn-canvas-w, set by canvas.js, persisted per browser), so
 * the conversation reflows beside the document instead of under it.
 * Phones: a full-screen sheet over everything but the history drawer.
 *
 * Logical properties only; colours from the theme variables (light and dark
 * follow css-variables.twig). Motion is off under prefers-reduced-motion.
 */

/* [Doona:START] - Message parts P3: Canvas */
/* Elevation tokens (DESIGN-ELEVATION.md §1): the shared --elev-* values when
   the app defines them, the spec's own values until then. */
:root {
  --dn-surface-2: var(--elev-surface-2, #fff);
  --dn-surface-3: var(--elev-surface-3, #fff);
  --dn-shadow-1: var(--elev-shadow-1, 0 1px 2px rgb(0 0 0 / 0.04));
  --dn-shadow-3: var(--elev-shadow-3, 0 2px 6px rgb(0 0 0 / 0.04), 0 12px 32px rgb(0 0 0 / 0.07));
  --dn-group: var(--elev-group, rgb(120 120 128 / 0.07));
  --dn-group-hover: var(--elev-group-hover, rgb(120 120 128 / 0.11));
  --dn-fill-1: var(--elev-fill-1, rgb(120 120 128 / 0.2));
  --dn-fill-2: var(--elev-fill-2, rgb(120 120 128 / 0.16));
  --dn-fill-3: var(--elev-fill-3, rgb(120 120 128 / 0.12));
  --dn-fill-4: var(--elev-fill-4, rgb(120 120 128 / 0.08));
  --dn-hover: var(--elev-hover, rgb(120 120 128 / 0.1));
  --dn-pressed: var(--elev-pressed, rgb(120 120 128 / 0.18));
  --dn-thumb: var(--elev-thumb, #fff);
  --dn-focus: var(--elev-focus-ring, rgb(120 122 126));
}

html[data-mode="dark"] {
  --dn-surface-2: var(--elev-surface-2, rgb(34 35 39));
  --dn-surface-3: var(--elev-surface-3, rgb(40 41 46));
  --dn-shadow-1: var(--elev-shadow-1, 0 1px 2px rgb(0 0 0 / 0.2));
  --dn-shadow-3: var(--elev-shadow-3, 0 4px 16px rgb(0 0 0 / 0.2), 0 16px 40px rgb(0 0 0 / 0.2));
  --dn-group: var(--elev-group, rgb(255 255 255 / 0.05));
  --dn-group-hover: var(--elev-group-hover, rgb(255 255 255 / 0.08));
  --dn-fill-1: var(--elev-fill-1, rgb(120 120 128 / 0.36));
  --dn-fill-2: var(--elev-fill-2, rgb(120 120 128 / 0.32));
  --dn-fill-3: var(--elev-fill-3, rgb(120 120 128 / 0.24));
  --dn-fill-4: var(--elev-fill-4, rgb(120 120 128 / 0.18));
  --dn-hover: var(--elev-hover, rgb(255 255 255 / 0.06));
  --dn-pressed: var(--elev-pressed, rgb(255 255 255 / 0.1));
  --dn-thumb: var(--elev-thumb, rgb(84 85 90));
  --dn-focus: var(--elev-focus-ring, rgb(170 172 176));
}

:root {
  --dn-canvas-w: 560px;
  /* The iOS sheet curve: fast out, long soft settle. */
  --dn-canvas-ease: cubic-bezier(0.32, 0.72, 0, 1);
}

/* No lines: the panel is a raised surface (surface-2) lifted off the chat by
   shadow-3, with rounded corners on the side that faces
   the conversation. Header, toolbar and body share that surface; the toolbar
   gets a soft shadow only once the document scrolls under it. */
.dn-canvas {
  --dn-canvas-bg: var(--dn-surface-2);
  --dn-canvas-fill: var(--dn-fill-3);
  --dn-canvas-fill-strong: var(--dn-pressed);
  position: fixed;
  inset-block: 0;
  inset-inline-end: 0;
  z-index: 30;
  display: flex;
  flex-direction: column;
  inline-size: var(--dn-canvas-w);
  max-inline-size: 70vw;
  background: var(--dn-canvas-bg);
  border-start-start-radius: 24px;
  border-end-start-radius: 24px;
  box-shadow: var(--dn-shadow-3);
  overflow: hidden;
}

.dn-canvas--enter {
  transition: transform 320ms var(--dn-canvas-ease), opacity 200ms ease-out;
}

.dn-canvas--leave {
  transition: transform 200ms ease-in, opacity 160ms ease-in;
}

.dn-canvas--from {
  opacity: 0;
  transform: translateX(-24px);
}

.dn-canvas--to {
  opacity: 1;
  transform: none;
}

html[dir="ltr"] .dn-canvas--from {
  transform: translateX(24px);
}

@media (min-width: 64rem) {
  html[data-canvas="open"] #content {
    margin-inline-end: var(--dn-canvas-w);
  }

  html[data-canvas="open"] .dn-chat-toolbar {
    inset-inline-end: calc(var(--dn-canvas-w) + 2.5rem);
  }

  /* The floating help button (snippets/script-tags/support-help.twig) is
     pinned to the physical left, which in RTL is the panel's side: it would
     sit on the document's text. It steps aside while the panel is open and
     comes back when it closes. (Below 64rem it is hidden anyway.) */
  html[data-canvas="open"]:not([dir="ltr"]) #doona-chat-btn {
    visibility: hidden;
    opacity: 0;
    pointer-events: none;
    animation: none;
    transition: opacity 150ms ease-out, visibility 0s linear 150ms;
  }

  html[data-canvas-resizing],
  html[data-canvas-resizing] * {
    cursor: col-resize !important;
    user-select: none;
  }
}

.dn-canvas__resize {
  position: absolute;
  inset-block: 0;
  inset-inline-start: 0;
  inline-size: 10px;
  cursor: col-resize;
  z-index: 2;
  touch-action: none;
}

.dn-canvas__resize::after {
  content: "";
  position: absolute;
  inset-block: 50% auto;
  inset-inline-start: 3px;
  inline-size: 4px;
  block-size: 40px;
  margin-block-start: -20px;
  border-radius: 4px;
  background: var(--dn-fill-1);
  opacity: 0;
  transition: opacity 150ms;
}

.dn-canvas__resize:hover::after,
.dn-canvas__resize:focus-visible::after {
  opacity: 1;
}

.dn-canvas__resize:focus-visible {
  outline: 2px solid var(--dn-focus);
  outline-offset: -2px;
}

/* ---- header ---- */

.dn-canvas__head {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  padding-block: 18px 6px;
  padding-inline: 24px 12px;
}

.dn-canvas__grip {
  display: none;
}

.dn-canvas__titles {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-inline-size: 0;
  flex-grow: 1;
  padding-block-start: 4px;
}

/* Two lines before an ellipsis; the full title is the tooltip. */
.dn-canvas__title {
  display: -webkit-box;
  margin: 0;
  overflow: hidden;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  font-size: 1.0625rem;
  font-weight: 700;
  line-height: 1.6;
  text-wrap: pretty;
  overflow-wrap: anywhere;
  color: var(--color-content);
}

.dn-canvas__title:focus {
  outline: none;
}

/* A Latin title (dir=auto, e.g. «main.py») still lines up with the Persian
   meta under it: aligned to the page's side, its own text direction kept. */
html[dir="rtl"] .dn-canvas__title,
html[dir="rtl"] .dn-artifact__title {
  text-align: right;
}

html[dir="ltr"] .dn-canvas__title,
html[dir="ltr"] .dn-artifact__title {
  text-align: left;
}

/* Code blocks in the panel sit on their own fill; no frame line. */
.dn-canvas x-code pre,
.dn-doc x-code pre {
  border: 0;
}

.dn-canvas__meta {
  min-block-size: 1.25rem;
  font-size: 0.8125rem;
  color: var(--color-content-dimmed);
}

.dn-canvas__live {
  font-weight: 500;
}

/* ---- buttons: 40px targets (44px on phones), feedback on press ---- */

.dn-canvas__icon,
.dn-canvas__step {
  display: inline-flex;
  flex-shrink: 0;
  align-items: center;
  justify-content: center;
  inline-size: 40px;
  block-size: 40px;
  border-radius: 12px;
  font-size: 1.25rem;
  color: var(--color-content-dimmed);
  transition: background-color 160ms ease-out, color 160ms ease-out, transform 160ms ease-out;
  -webkit-tap-highlight-color: transparent;
}

.dn-canvas__icon:hover,
.dn-canvas__step:not(:disabled):hover {
  background: var(--dn-hover);
  color: var(--color-content);
}

/* Instant on press, eased on release. */
.dn-canvas__icon:active,
.dn-canvas__step:not(:disabled):active,
.dn-canvas__mode:active,
.dn-canvas__link:active,
.dn-canvas__restore:not(:disabled):active {
  transform: scale(0.94);
  transition-duration: 0ms;
}

.dn-canvas__icon:active,
.dn-canvas__step:not(:disabled):active {
  background: var(--dn-canvas-fill-strong);
}

.dn-canvas__step:disabled {
  color: var(--color-content-super-dimmed);
  cursor: default;
}

.dn-canvas__icon:focus-visible,
.dn-canvas__mode:focus-visible,
.dn-canvas__step:focus-visible,
.dn-canvas__link:focus-visible {
  outline: 2px solid var(--dn-focus);
  outline-offset: 2px;
}

/* ---- toolbar ---- */

.dn-canvas__bar {
  position: relative;
  z-index: 1;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 6px 12px;
  padding-block: 4px 10px;
  padding-inline: 16px 12px;
  background: var(--dn-canvas-bg);
  transition: box-shadow 200ms ease-out;
}

/* The document has scrolled under it: a soft edge, not a rule. */
.dn-canvas.is-scrolled .dn-canvas__bar,
.dn-canvas.is-scrolled .dn-canvas__old {
  box-shadow: 0 8px 16px -12px rgb(0 0 0 / 0.25);
}

.dn-canvas__versions {
  display: flex;
  align-items: center;
  gap: 2px;
  font-size: 0.875rem;
  color: var(--color-content-dimmed);
}

.dn-canvas__version {
  min-inline-size: 5.5em;
  text-align: center;
  font-variant-numeric: tabular-nums;
  color: var(--color-content);
}

.dn-canvas__tools,
.dn-canvas__icons {
  display: flex;
  align-items: center;
  gap: 4px;
  margin-inline-start: auto;
}

/* Segmented control: a filled track, the chosen segment a raised fill. */
.dn-canvas__modes {
  display: flex;
  padding: 3px;
  border-radius: 12px;
  background: var(--dn-canvas-fill);
}

.dn-canvas__mode {
  min-block-size: 34px;
  padding-inline: 14px;
  border-radius: 9px;
  font-size: 0.8125rem;
  font-weight: 500;
  color: var(--color-content-dimmed);
  transition: background-color 160ms ease-out, color 160ms ease-out, transform 160ms ease-out;
}

.dn-canvas__mode:hover {
  color: var(--color-content);
}

.dn-canvas__mode[aria-pressed="true"] {
  background: var(--dn-thumb);
  color: var(--color-content);
  box-shadow: var(--dn-shadow-1);
}


/* ---- an older version on screen ---- */

.dn-canvas__old {
  position: relative;
  z-index: 1;
  padding-block: 0 10px;
  padding-inline: 16px;
  background: var(--dn-canvas-bg);
}

.dn-canvas__old-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 8px 12px;
  padding-block: 10px;
  padding-inline: 14px 10px;
  border-radius: 14px;
  background: rgb(245 158 11 / 0.14);
  font-size: 0.875rem;
  line-height: 1.7;
  color: var(--color-content);
}

.dn-canvas__old-text {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

.dn-canvas__old-text i {
  font-size: 1.125rem;
  color: #d97706;
}

.dn-canvas__old-actions {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin-inline-start: auto;
}

/* Gray button (never bare text beside the Filled «بازگرداندن»). */
.dn-canvas__link {
  min-block-size: 36px;
  padding-inline: 12px;
  border-radius: 10px;
  background: var(--dn-fill-3);
  font-size: 0.8125rem;
  font-weight: 500;
  color: var(--color-content);
  transition: background-color 160ms ease-out, color 160ms ease-out, transform 160ms ease-out;
}

.dn-canvas__link:disabled {
  opacity: 0.5;
  cursor: default;
}

.dn-canvas__link:not(:disabled):hover {
  background: var(--dn-fill-2);
}

.dn-canvas__link:not(:disabled):active {
  background: var(--dn-fill-1);
}

.dn-canvas__restore {
  min-block-size: 36px;
  padding-inline: 14px;
  border: 0;
  border-radius: 10px;
  background: var(--color-content);
  color: var(--color-main);
  font-weight: 600;
  transition: transform 160ms ease-out, opacity 160ms ease-out;
}

.dn-canvas__restore:disabled {
  opacity: 0.5;
}

/* ---- body ---- */

.dn-canvas__body {
  position: relative;
  flex-grow: 1;
  min-block-size: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
}

.dn-canvas__doc {
  min-block-size: 100%;
}

.dn-canvas__doc.is-stale {
  opacity: 0.6;
  transition: opacity 150ms ease-out;
}

.dn-canvas__prose {
  padding-block: 20px 64px;
  padding-inline: 32px;
}

/* In a wide panel the text keeps a reading measure and sits in the middle. */
.dn-canvas__prose x-markdown > div {
  max-inline-size: 42rem;
  margin-inline: auto;
}

.dn-canvas__code {
  padding: 16px;
}

.dn-canvas__plain {
  margin: 0;
  padding: 16px;
  overflow-x: auto;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.8125rem;
  line-height: 1.6;
  white-space: pre;
  color: var(--color-content);
}

.dn-canvas__error {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 14px;
  min-block-size: 60%;
  padding: 32px;
  font-size: 0.9375rem;
  line-height: 1.8;
  text-align: center;
  color: var(--color-content-dimmed);
}

.dn-canvas__error > i {
  font-size: 1.75rem;
  color: var(--color-failure);
}

.dn-canvas__retry {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-block-size: 40px;
  padding-inline: 16px;
  border-radius: 12px;
  background: var(--dn-fill-3);
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--color-content);
  transition: background-color 160ms ease-out, transform 160ms ease-out;
}

.dn-canvas__retry:hover {
  background: var(--dn-fill-2);
}

.dn-canvas__retry:active {
  background: var(--dn-fill-1);
  transform: scale(0.96);
  transition-duration: 0ms;
}

.dn-canvas__retry:focus-visible {
  outline: 2px solid var(--dn-focus);
  outline-offset: 2px;
}

/* The document being written (or loading): a page-shaped placeholder whose
   light sweeps across it, start to end. Still under reduced motion. */
.dn-canvas__ghost {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 14px;
  max-inline-size: 42rem;
  margin-inline: auto;
  padding-block: 24px;
  padding-inline: 32px;
}

.dn-canvas__ghost-line {
  display: block;
  block-size: 12px;
  border-radius: 6px;
  background:
    linear-gradient(90deg, transparent 0%, var(--dn-hover) 50%, transparent 100%) 0 0 / 200% 100% no-repeat,
    var(--dn-fill-4);
  animation: dn-canvas-sweep 1.6s ease-in-out infinite;
}

.dn-canvas__ghost-line.is-title {
  inline-size: 62%;
  block-size: 22px;
  margin-block-end: 10px;
  border-radius: 8px;
}

.dn-canvas__ghost-line.is-heading {
  inline-size: 38%;
  block-size: 16px;
  margin-block-start: 18px;
}

.dn-canvas__ghost-line.is-short {
  inline-size: 72%;
}

.dn-canvas__ghost-line.is-mid {
  inline-size: 86%;
}

.dn-canvas__ghost-pen {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  inline-size: 36px;
  block-size: 36px;
  margin-block-start: 6px;
  border-radius: 12px;
  background: var(--dn-canvas-fill);
  font-size: 1.125rem;
  color: var(--color-content-dimmed);
  animation: dn-canvas-breathe 1.6s ease-in-out infinite;
}

.dn-canvas__ghost.is-loading .dn-canvas__ghost-pen {
  display: none;
}

@keyframes dn-canvas-sweep {
  from { background-position: 150% 0, 0 0; }
  to { background-position: -50% 0, 0 0; }
}

html[dir="rtl"] .dn-canvas__ghost-line {
  animation-direction: reverse;
}

@keyframes dn-canvas-breathe {
  0%, 100% { opacity: 0.55; }
  50% { opacity: 1; }
}

/* <x-sandbox>: the iframe fills the body; the page inside is white like a
   browser page, whatever the theme. */
.dn-sandbox {
  display: block;
  block-size: 100%;
  min-block-size: 60vh;
}

.dn-sandbox__frame {
  display: block;
  inline-size: 100%;
  block-size: 100%;
  min-block-size: 60vh;
  border: 0;
  background: #fff;
}

/* Phones (and tablets): a full-screen sheet. It rises and falls on the iOS
   sheet curve; a drag that is let go short of dismissing settles back on
   it too (sheet-drag.js clears its inline transition on release). */
@media (max-width: 63.98rem) {
  .dn-canvas {
    inset: 0;
    z-index: 95;
    inline-size: auto;
    max-inline-size: none;
    --dn-canvas-bg: var(--dn-surface-3);
    border-radius: 0;
    box-shadow: none;
    padding-block-end: env(safe-area-inset-bottom);
    transition: translate 360ms var(--dn-canvas-ease);
  }

  .dn-canvas--enter {
    transition: transform 420ms var(--dn-canvas-ease);
  }

  /* Close and Escape slide it down from JS (canvasDismiss), and a drag
     slides it out before closing; the leave itself is instant. */
  .dn-canvas--leave {
    transition: none;
    /* Stay below the screen for the frame between the slide's end and the
       element hiding, or that frame paints it full-screen again. */
    translate: 0 100%;
  }

  .dn-canvas--from {
    opacity: 1;
    transform: translateY(100%);
  }

  html[dir="ltr"] .dn-canvas--from {
    transform: translateY(100%);
  }

  .dn-canvas__resize {
    display: none;
  }

  .dn-canvas__head {
    position: relative;
    padding-block-start: calc(24px + env(safe-area-inset-top));
    padding-inline: 18px 10px;
  }

  .dn-canvas__grip {
    display: block;
    position: absolute;
    inset-block-start: calc(8px + env(safe-area-inset-top));
    inset-inline-start: 50%;
    inline-size: 40px;
    block-size: 5px;
    margin-inline-start: -20px;
    border-radius: 5px;
    background: var(--dn-fill-1);
  }

  .dn-canvas__icon,
  .dn-canvas__step {
    inline-size: 44px;
    block-size: 44px;
  }

  .dn-canvas__mode {
    min-block-size: 38px;
  }

  .dn-canvas__bar {
    padding-inline: 10px 8px;
  }

  .dn-canvas__prose,
  .dn-canvas__ghost {
    padding-inline: 20px;
  }

  html[data-canvas="open"] body {
    overflow: hidden;
  }
}

@media (prefers-reduced-motion: reduce) {
  .dn-canvas,
  .dn-canvas--enter,
  .dn-canvas--leave {
    transition: opacity 150ms ease-out;
  }

  .dn-canvas--from,
  html[dir="ltr"] .dn-canvas--from {
    transform: none;
  }

  .dn-canvas__ghost-line,
  .dn-canvas__ghost-pen {
    animation: none;
  }
}

@media (prefers-contrast: more) {
  .dn-canvas {
    box-shadow: 0 0 0 1px var(--color-line);
  }
}

/* ---- reading typography ---------------------------------------------------
 * .dn-doc: a written document, in the panel (.dn-canvas__prose) and in an
 * inline card (.dn-artifact__body). The same rules in both places, so an
 * email reads the same in the card and in the panel. The panel is teleported
 * to <body>, outside .message, so none of the chat's prose rules reach it.
 * Inside a card the chat's prose rules (message.css, in Tailwind's
 * `@layer components`) still apply, and these win over them because this
 * bundle is unlayered, whatever the specificity; so everything prose sets
 * that would make a card differ from the panel is reset here too (backticks
 * around inline code, italic and quote marks on blockquotes, weights).
 *
 * Persian wants generous leading (tall ascenders and descenders, dots and
 * diacritics above and below the line): body 1.95, headings tighter as they
 * grow. No letter-spacing anywhere: tracking breaks Persian letter joining.
 * Sizes are in rem/em so a larger browser text size scales the whole page.
 * markdown.js stamps dir on each top-level block; everything here is logical
 * (start/end), so an English paragraph inside a Persian document lines up on
 * its own side. Code is LTR by the base rule in base.twig. */
.dn-doc x-markdown > div {
  font-size: 1rem;
  line-height: 1.95;
  color: var(--color-content);
  overflow-wrap: break-word;
}

.dn-doc x-markdown > div > * {
  margin-block: 0 1.1em;
}

.dn-doc x-markdown > div > :first-child {
  margin-block-start: 0;
}

.dn-doc x-markdown > div > :last-child {
  margin-block-end: 0;
}

.dn-doc x-markdown p {
  margin-block: 0 1.1em;
}

/* A global `p { line-height: 1.7 }` (base styles) would otherwise win over
   the inherited body leading. */
.dn-doc x-markdown :is(p, li, blockquote, dd, dt) {
  line-height: inherit;
}

.dn-doc x-markdown h1,
.dn-doc x-markdown h2,
.dn-doc x-markdown h3,
.dn-doc x-markdown h4,
.dn-doc x-markdown h5,
.dn-doc x-markdown h6 {
  font-family: inherit;
  font-weight: 700;
  color: var(--color-content);
  text-wrap: balance;
}

.dn-doc x-markdown h1 {
  margin-block: 1.75em 0.7em;
  font-size: 1.625em;
  font-weight: 800;
  line-height: 1.45;
}

.dn-doc x-markdown h2 {
  margin-block: 1.75em 0.6em;
  font-size: 1.3125em;
  line-height: 1.55;
}

.dn-doc x-markdown h3 {
  margin-block: 1.6em 0.5em;
  font-size: 1.125em;
  line-height: 1.65;
}

.dn-doc x-markdown h4,
.dn-doc x-markdown h5,
.dn-doc x-markdown h6 {
  margin-block: 1.4em 0.4em;
  font-size: 1em;
  line-height: 1.8;
}

.dn-doc x-markdown h1 + h2,
.dn-doc x-markdown h2 + h3,
.dn-doc x-markdown h3 + h4 {
  margin-block-start: 0.5em;
}

.dn-doc x-markdown strong {
  font-weight: 700;
  color: var(--color-content);
}

.dn-doc x-markdown a {
  color: inherit;
  font-weight: inherit;
  text-decoration: underline;
  text-decoration-color: var(--color-content-super-dimmed);
  text-decoration-thickness: 1px;
  text-underline-offset: 0.3em;
}

.dn-doc x-markdown a:hover {
  text-decoration-color: currentColor;
}

.dn-doc x-markdown ul,
.dn-doc x-markdown ol {
  padding-inline-start: 1.6em;
}

.dn-doc x-markdown ul {
  list-style-type: disc;
}

.dn-doc x-markdown ul ul {
  list-style-type: circle;
}

.dn-doc x-markdown ol {
  list-style-type: decimal;
}

/* A Persian list counts in Persian digits, like the rest of the interface. */
.dn-doc x-markdown ol[dir="rtl"],
.dn-doc x-markdown [dir="rtl"] ol {
  list-style-type: persian;
}

.dn-doc x-markdown li {
  margin-block: 0.3em;
  padding-inline-start: 0.25em;
}

.dn-doc x-markdown li::marker {
  color: var(--color-content-dimmed);
}

.dn-doc x-markdown li > p {
  margin-block: 0;
}

.dn-doc x-markdown li > ul,
.dn-doc x-markdown li > ol {
  margin-block: 0.4em 0;
}

.dn-doc x-markdown blockquote {
  font-style: normal;
  font-weight: inherit;
  quotes: none;
  padding-block: 0.75em;
  padding-inline: 1.1em;
  border-radius: 14px;
  background: var(--dn-group);
  color: var(--color-content-dimmed);
}

.dn-doc x-markdown blockquote > :last-child {
  margin-block-end: 0;
}

.dn-doc x-markdown hr {
  inline-size: 3em;
  block-size: 4px;
  margin-block: 2.2em;
  margin-inline: auto;
  border: 0;
  border-radius: 4px;
  background: var(--dn-fill-2);
}

/* A wide table scrolls on its own instead of widening the page. No rules:
   a rounded tinted block, a stronger tint on the header row and on every
   other row, and cell padding that keeps a wrapped cell clear of the next
   column. The tints are the elevation fills, translucent, so they read one
   step up in either theme. */
.dn-doc x-markdown table {
  display: block;
  inline-size: max-content;
  max-inline-size: 100%;
  overflow-x: auto;
  border-radius: 14px;
  border-collapse: separate;
  border-spacing: 0;
  /* The whole table is one grouped surface, so odd rows never float on the
     page background; the header and even rows are one step stronger. */
  background: var(--dn-group);
  font-size: 0.9375em;
  line-height: 1.7;
}

.dn-doc x-markdown th,
.dn-doc x-markdown td {
  min-inline-size: 5.5em;
  padding-block: 0.65em;
  padding-inline: 1em;
  border: 0;
  text-align: start;
  vertical-align: top;
}

.dn-doc x-markdown th {
  font-weight: 700;
  white-space: nowrap;
  background: var(--dn-fill-3);
}

.dn-doc x-markdown tbody tr:nth-child(even) td {
  background: var(--dn-fill-4);
}

/* Inline code. x-code always marks its own <code> .hljs; matching on that
   keeps the selector simple enough for every browser. */
.dn-doc x-markdown code:not(.hljs) {
  padding-block: 0.1em;
  padding-inline: 0.4em;
  border-radius: 6px;
  background: var(--dn-fill-3);
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.875em;
  font-weight: inherit;
}

.dn-doc x-markdown code:not(.hljs)::before,
.dn-doc x-markdown code:not(.hljs)::after,
.dn-doc x-markdown blockquote p::before,
.dn-doc x-markdown blockquote p::after {
  content: none;
}

.dn-doc x-markdown x-code,
.dn-doc x-markdown x-code pre {
  display: block;
  line-height: 1.6;
}

/* The light highlight.js theme paints its own near-white box inside the
   block's grey wrapper. */
.dn-doc x-markdown x-code .hljs {
  background: transparent;
}

.dn-doc x-markdown img {
  margin-block: 0;
  max-inline-size: 100%;
  border-radius: 12px;
}

/* ---- cards in the chat ----------------------------------------------------
 * No outlines: a tinted surface. A finished document's whole card opens it
 * (the Open button's hit area is stretched over the card); the title wraps
 * to two lines; in a narrow column (the panel open beside the chat) Open
 * shrinks to its icon, keeping its label for screen readers. */

.dn-artifact {
  --dn-card-fill: var(--dn-group);
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 12px;
  inline-size: min(100%, 560px);
  margin-block: 4px;
  padding-block: 12px;
  padding-inline: 12px 14px;
  border-radius: 18px;
  background: var(--dn-card-fill);
  container-type: inline-size;
  transition: background-color 160ms ease-out, transform 160ms ease-out;
}

.dn-artifact.is-openable:hover {
  background: var(--dn-group-hover);
  box-shadow: var(--dn-shadow-1);
}

.dn-artifact.is-openable:active {
  transform: scale(0.99);
  transition-duration: 0ms;
}

.dn-artifact.is-inline {
  inline-size: 100%;
  max-inline-size: 720px;
}

/* Stopped or left unfinished: quieter, by colour rather than opacity (the
   card at 0.75 left its secondary text at 3.17:1). */
.dn-artifact.is-muted .dn-artifact__title {
  color: var(--color-content-dimmed);
}

/* Not written: the error tint (DESIGN-ELEVATION §1.4 danger fill), a red
   mark, and a way on («تلاش دوباره» asks for the answer again). */
.dn-artifact.is-failed {
  --dn-card-fill: var(--elev-danger-fill, rgb(254 81 87 / 0.1));
}

.dn-artifact.is-failed .dn-artifact__icon {
  background: color-mix(in srgb, var(--color-failure) 14%, transparent);
  color: var(--color-failure);
}

.dn-artifact__retry {
  flex-shrink: 0;
  padding-inline: 12px;
}

.dn-artifact__head {
  display: flex;
  align-items: center;
  gap: 12px;
  min-inline-size: 0;
}

.dn-artifact__icon {
  display: inline-flex;
  flex-shrink: 0;
  align-items: center;
  justify-content: center;
  inline-size: 40px;
  block-size: 40px;
  border-radius: 12px;
  background: var(--dn-fill-4);
  font-size: 1.25rem;
  color: var(--color-content-dimmed);
}

.dn-artifact.is-writing .dn-artifact__icon {
  color: var(--color-content);
}

.dn-artifact__titles {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex-grow: 1;
  min-inline-size: 0;
}

.dn-artifact__title {
  display: -webkit-box;
  overflow: hidden;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  font-size: 0.9375rem;
  font-weight: 700;
  line-height: 1.6;
  overflow-wrap: anywhere;
  color: var(--color-content);
}

.dn-artifact__meta {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  font-size: 0.75rem;
  color: var(--color-content-dimmed);
}

/* Open: a Gray button (never bare): fill-3 at rest, one step stronger
   while the card is hovered, strongest on press. */
.dn-artifact__open {
  display: inline-flex;
  flex-shrink: 0;
  align-items: center;
  justify-content: center;
  gap: 6px;
  min-block-size: 40px;
  min-inline-size: 40px;
  white-space: nowrap;
  padding-inline: 14px;
  border-radius: 12px;
  background: var(--elev-fill-3, rgb(120 120 128 / 0.16));
  color: var(--color-content);
  font-size: 0.8125rem;
  font-weight: 600;
  transition: background-color 160ms ease-out, transform 160ms ease-out;
}

.dn-artifact__open i {
  font-size: 1.125rem;
}

/* The whole card is the target. */
.dn-artifact__open::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 18px;
}

.dn-artifact.is-openable:hover .dn-artifact__open {
  background: var(--elev-fill-2, rgb(120 120 128 / 0.2));
}

.dn-artifact__open:active {
  /* No transform here: it would make the button the containing block of
     its stretched ::after and shrink the card's hit area mid-click. */
  background: var(--elev-fill-1, rgb(120 120 128 / 0.28));
  transition-duration: 0ms;
}

.dn-artifact__open:focus-visible {
  outline: 2px solid var(--dn-focus);
  outline-offset: 2px;
}

/* Touch: a 44px button (the whole card is the target anyway). */
@media (pointer: coarse) {
  .dn-artifact__open,
  .dn-artifact__action {
    min-block-size: 44px;
  }

  .dn-artifact__open {
    min-inline-size: 44px;
  }
}

/* Only a really narrow card drops the label; a phone's card keeps «باز
   کردن» (was 420px, which made every phone show a bare icon). */
@container (max-width: 280px) {
  .dn-artifact__open {
    padding-inline: 0;
    inline-size: 40px;
  }

  .dn-artifact__open-label {
    position: absolute;
    inline-size: 1px;
    block-size: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }
}

.dn-artifact__inline {
  padding-block-start: 4px;
}

.dn-artifact__body.is-clamped {
  position: relative;
  max-block-size: 18rem;
  overflow: hidden;
  -webkit-mask-image: linear-gradient(to bottom, #000 75%, transparent);
  mask-image: linear-gradient(to bottom, #000 75%, transparent);
}

.dn-artifact__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-block-start: 10px;
}

.dn-artifact__action {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  min-block-size: 36px;
  padding-inline: 8px;
  border-radius: 10px;
  font-size: 0.8125rem;
  font-weight: 500;
  /* Gray button (never bare). */
  background: var(--elev-fill-3, rgb(120 120 128 / 0.16));
  color: var(--color-content);
  transition: background-color 160ms ease-out, color 160ms ease-out, transform 160ms ease-out;
}

.dn-artifact__action:hover {
  background: var(--elev-fill-2, rgb(120 120 128 / 0.2));
}

.dn-artifact__action:active {
  background: var(--elev-fill-1, rgb(120 120 128 / 0.28));
  transform: scale(0.97);
  transition-duration: 0ms;
}

.dn-artifact__action:focus-visible {
  outline: 2px solid var(--dn-focus);
  outline-offset: 2px;
}

.dn-artifact__failed {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 16px;
  font-size: 0.8125rem;
  color: var(--color-content-dimmed);
}

.dn-artifact__loading {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.dn-artifact__loading .loading {
  display: block;
  block-size: 12px;
  border-radius: 6px;
}

.dn-artifact__loading .loading:last-child {
  inline-size: 70%;
}

@media (prefers-reduced-motion: reduce) {
  .dn-canvas__live.shimmer {
    animation: none;
    -webkit-mask-image: none;
  }
}
/* More contrast: the one place a line is allowed, so the card has an edge. */
@media (prefers-contrast: more) {
  .dn-artifact {
    box-shadow: inset 0 0 0 1px var(--color-line);
  }
}

/* No translucency wanted: solid fills instead of see-through ones. */
@media (prefers-reduced-transparency: reduce) {
  :root {
    --dn-group: rgb(240 240 242);
    --dn-group-hover: rgb(232 232 235);
    --dn-fill-3: rgb(228 228 231);
    --dn-fill-4: rgb(236 236 239);
  }

  html[data-mode="dark"] {
    --dn-group: rgb(44 45 49);
    --dn-group-hover: rgb(52 53 57);
    --dn-fill-3: rgb(64 65 70);
    --dn-fill-4: rgb(56 57 62);
  }
}
/* [Doona:END] */

/*
 * Model names and other Latin text: Latin digits. Model names also read as
 * their own left-to-right run.
 *
 * :root turns on IRANYekanXV's stylistic set "ss02" (snippets/css-variables.twig),
 * which draws 0-9 as Persian digits everywhere. A model name ("Sonnet 5.5",
 * "GPT 6.1 Sol", "Kling 3") is a product name and keeps its Latin digits.
 * The marker is set by the Twig filter `model_name`, the Alpine directive
 * `x-model-name` and modelNameHtml() — resources/assets/js/model-name.js.
 *
 * !important and the tripled class: the legacy "keep Persian digits" rules
 * (base/latin-digits.css, `modal-element[name="models"] .model-price *`,
 * specificity 0,2,1) are !important too, and a model name must win wherever
 * it sits. font-feature-settings replaces the whole list, so this only drops
 * ss02, which is the only feature :root sets.
 */
.model-name.model-name.model-name,
.model-name.model-name.model-name * {
  font-feature-settings: "ss02" off !important;
}

/*
 * Latin text in general: the same switch, for everything that is not a
 * model name but is still Latin by nature — keys, URLs, code, IBANs, hex
 * colours, emails, coupon codes, and Latin words inside Persian prose
 * ("GPT-4o", "k6", "S3", "Claude 3.5").
 *
 * The one mechanism (DESIGN-ELEVATION.md §1.7):
 *   - `.latin` on any element: Latin digits for it and everything in it.
 *     In a template, pair it with dir="ltr" when the value must also read
 *     left to right as its own run (a key, URL, IBAN, hex, email):
 *       <code class="latin" dir="ltr">sk-dn-7f3a…</code>
 *       <input class="input latin" dir="ltr" type="text" …>
 *     The dir attribute isolates the run (UA style), so it never reorders
 *     the Persian text around it — no extra CSS needed.
 *   - `lang="en"` (any element whose language is English — `:lang(en)`):
 *     message content marks Latin runs this way (markLatinRuns() in
 *     resources/assets/js/model-name.js, called by app/markdown.js). It
 *     only changes the digits, never the bidi order, so the markdown
 *     direction policy stays the sole writer of `dir` in messages.
 *   - Without any marker: code, keyboard and sample text, and URL, email
 *     and search fields are Latin by nature. A dir="ltr" field alone is
 *     not (the phone/OTP fields keep Persian digits) — add `.latin`.
 *
 * Persian digits that are really Persian codepoints (U+06F0…) stay Persian
 * either way: this only stops ASCII digits from being redrawn.
 */
.latin.latin.latin,
.latin.latin.latin *,
:lang(en),
code,
kbd,
samp,
pre,
x-code,
input[type="url"],
input[type="email"],
input[type="search"],
x-markdown [dir="ltr"] {
  font-feature-settings: "ss02" off !important;
}

/* Isolated LTR run: "GPT 6.1 Sol" keeps its order inside Persian text and
 * does not pull the neighbouring punctuation into its direction. The marker
 * goes on an inline element (a block would turn left-aligned); an <option>
 * cannot be isolated and only gets the digits. */
.model-name:not(option, select) {
  direction: ltr;
  unicode-bidi: isolate;
}

/* A marked span that its parent blockifies (a flex/grid item: `flex-col`
 * stretches it to the full width) would align to its own LTR start, i.e.
 * the left. match-parent resolves start against the parent's direction, so
 * it stays right-aligned on RTL pages (a centred parent stays centred).
 * Chrome and Safari only know the -webkit- spelling (measured: Chrome
 * ignores the plain one); each browser keeps the last one it parses.
 * :where() keeps it at zero specificity, so a page rule in these modules
 * still wins; a Tailwind text-* utility (layered) would not, so align the
 * parent, not the name. */
:where(.model-name:not(option, select)) {
  text-align: match-parent;
  text-align: -webkit-match-parent;
}

/* The models modal let a card's name wrap to two lines through a selector
 * on the h3's old x-text binding (base/misc-list-voices-library-tweaks.css).
 * The name now sits in a marked span inside the h3, so that selector no
 * longer matches; this keeps the two lines. */
modal-element[name="models"] h3:has(> .model-name) {
  line-clamp: 2;
  -webkit-line-clamp: 2;
}

/*
 * Private mode (F2): the whole app changes look while the mode is on, so the
 * person knows at a glance where they are — like Instagram's Vanish mode.
 *
 * One switch: <html data-private>. base.twig renders it on the first frame
 * when the private cookie is present (no flash of the normal theme), and
 * private-mode.js paint() keeps it in step on every change and Turbo visit.
 *
 * Built on the elevation tokens (DESIGN-ELEVATION): the theme re-tints the
 * surface / fill / tint tokens (and the --color-* tokens the rest of the app
 * still reads), so every primitive that uses them follows. Until the
 * elevation foundation is on main, the few surfaces hard-coded per theme
 * (composer, sidebar shell, user bubble, mobile header button, bottom nav,
 * nav drawer, account menu card) are re-pointed at the same values. No
 * lines anywhere (§0): only surfaces, fills and the existing soft shadows.
 *
 *   dark  -> near-black with a deep indigo tint (Vanish is always dark)
 *   light -> a clearly lavender-tinted light theme. A forced dark theme in
 *            light mode would put light text on surfaces hard-coded light.
 *
 * Contrast, computed (content / dimmed text on each surface):
 *   dark  bg 17.5/8.5, surface-1 16.3/7.9, surface-2 14.9/7.2,
 *         surface-3 13.7/6.6, bubble 12.2/5.9
 *   light bg 9.1/5.1, surface-1 8.3/4.7, surface-2 9.6/5.4, bubble 8.1/4.6
 *   accent buttons: dark 6.7, light 7.1.
 *
 * Entering and leaving crossfades through a view transition (paint()), a
 * composited snapshot fade: no element's own transitions are touched.
 *
 * Imported last in index.css: it must win over every module it re-tints.
 */

/* [Doona:START] - Private mode (F2) theme */

/* ---- Tokens ---------------------------------------------------------------- */
:root[data-private][data-mode="dark"] {
  --color-main: rgb(19 12 38);
  --color-intermediate: rgb(27 19 51);
  /* Lines are tinted but never MORE visible than the defaults (no lines,
     DESIGN-ELEVATION §0): line 2.2:1 on bg vs the default 3.1:1. */
  --color-line: rgb(84 70 130);
  --color-line-dimmed: rgb(62 50 102 / 67%);
  --color-line-super-dimmed: rgb(36 27 64);
  --color-button-dimmed: rgb(84 66 136);
  --color-accent: rgb(167 139 250);
  --color-accent-content: rgb(24 16 48);

  --elev-bg: rgb(19 12 38);
  --elev-surface-1: rgb(27 19 51);
  --elev-surface-2: rgb(36 26 66);
  --elev-surface-3: rgb(43 32 78);
  --elev-group: rgb(196 181 253 / 0.06);
  --elev-group-hover: rgb(196 181 253 / 0.09);
  --elev-fill-1: rgb(130 112 190 / 0.36);
  --elev-fill-2: rgb(130 112 190 / 0.32);
  --elev-fill-3: rgb(130 112 190 / 0.24);
  --elev-fill-4: rgb(130 112 190 / 0.18);
  --elev-hover: rgb(196 181 253 / 0.07);
  --elev-pressed: rgb(196 181 253 / 0.11);
  --elev-selected: rgb(196 181 253 / 0.10);
  --elev-thumb: rgb(84 70 130);
  --elev-tint: rgb(167 139 250);
  --elev-tint-text: rgb(196 181 253);

  --dn-private-surface: rgb(36 26 66);
  --dn-private-surface-strong: rgb(52 39 92);
  --dn-private-pill-bg: rgb(43 32 78);
  --dn-private-pattern: rgb(167 139 250 / 0.16);
  --dn-private-glow: rgb(124 58 237 / 0.30);
  color-scheme: dark;
}

:root[data-private][data-mode="light"] {
  --color-main: rgb(245 241 255);
  --color-intermediate: rgb(236 229 255);
  /* line 1.24:1 on bg vs the default 1.27:1 (bg-line tracks and skeletons
     stay visible); dimmed 1.06 vs 1.08. */
  --color-line: rgb(222 215 250);
  --color-line-dimmed: rgb(238 234 254);
  --color-line-super-dimmed: rgb(243 240 255);
  --color-button-dimmed: rgb(230 222 254);
  --color-accent: rgb(109 40 217);
  --color-accent-content: rgb(255 255 255);

  --elev-bg: rgb(245 241 255);
  --elev-surface-1: rgb(236 229 255);
  --elev-surface-2: rgb(250 248 255);
  --elev-surface-3: rgb(252 251 255);
  --elev-group: rgb(109 40 217 / 0.05);
  --elev-group-hover: rgb(109 40 217 / 0.08);
  --elev-fill-1: rgb(109 80 200 / 0.20);
  --elev-fill-2: rgb(109 80 200 / 0.16);
  --elev-fill-3: rgb(109 80 200 / 0.12);
  --elev-fill-4: rgb(109 80 200 / 0.08);
  --elev-hover: rgb(109 40 217 / 0.07);
  --elev-pressed: rgb(109 40 217 / 0.12);
  --elev-selected: rgb(109 40 217 / 0.10);
  --elev-tint: rgb(109 40 217);
  --elev-tint-text: rgb(91 33 182);

  --dn-private-surface: rgb(236 230 255);
  --dn-private-surface-strong: rgb(233 226 255);
  --dn-private-pill-bg: rgb(250 248 255);
  --dn-private-pattern: rgb(109 40 217 / 0.10);
  --dn-private-glow: rgb(139 92 246 / 0.18);
}

/* ---- The page: a violet glow from the top and a faint, static dot grid
   (the Vanish texture). Fixed, so it does not scroll or repaint. */
html[data-private] body {
  background-color: var(--color-main);
  background-image:
    radial-gradient(ellipse 90% 55% at 50% -12%, var(--dn-private-glow), transparent 70%),
    radial-gradient(var(--dn-private-pattern) 1px, transparent 1.3px);
  background-size: 100% 100%, 22px 22px;
  background-attachment: fixed, fixed;
}

@media (prefers-contrast: more) {
  html[data-private] body {
    background-image: none;
  }
}

/* The phone header is opaque bg-main, which cut the violet glow and the dot
   grid into two pieces under it. #content is the scroller (the header never
   sits over scrolling content), so the header lets the page show through. */
html[data-private] .doona-mobile-header {
  background-color: transparent;
}

/* ---- Surfaces hard-coded per theme on main -------------------------------- */
html[data-private] .doona-chat-inner,
html[data-private] .doona-chat-input-bar,
html[data-private] .doona-settings-btn {
  background-color: var(--dn-private-surface);
}

html[data-private] .doona-settings-btn:not(.dr-tier-off):not(.dr-tier-none) {
  background: color-mix(in oklab, currentColor 18%, var(--dn-private-surface));
}

/* The nav sidebar only: the history drawer (aside#sidebar) is bg-main. */
html[data-private] aside.sticky:not(#sidebar) {
  background: var(--elev-surface-1);
}

/* The user's message: the bubble (div.content) and its edit form. */
html[data-private] div.message[data-role="user"] > div.flex.flex-col.gap-2.min-w-0.grow div.content,
html[data-private] div.message[data-role="user"] > div.flex.flex-col.gap-2.min-w-0.grow > form {
  background-color: var(--dn-private-surface-strong);
}

html[data-private] .doona-mobile-header .doona-history-btn {
  background: var(--dn-private-surface);
}

/* The bottom nav is glass (doona/components/glass.css): its tint is mixed
   from --elev-surface-2, which this theme already sets, so it needs no
   override of its own. A `background` shorthand here used to wipe the
   material's sheen and stay translucent with glass off. */

html[data-private] .dnm-drawer,
html[data-private] .dam-card {
  background: var(--elev-surface-2);
}

/* The dashboard pins the red credit banner over the top of #content
   (position: absolute); in the flow it sits above the pill instead of
   under it. */
html[data-private] body[x-data="dashboard"] div#content > .py-3.bg-rose-600 {
  position: relative;
}

/* The dashboard paints its own background on #content (!important). */
html[data-private] body[x-data="dashboard"]:has(#quick-access) div#content {
  background: transparent !important;
}

/* ---- Enter / leave: one composited crossfade ------------------------------
   paint() wraps the attribute change in document.startViewTransition() and
   marks <html> with .dn-private-vt for its length, so only this switch gets
   the timing below (Turbo's own view transitions, if any, are untouched).
   Without the API, or under reduced motion, the theme simply switches. */
html.dn-private-vt::view-transition-old(root),
html.dn-private-vt::view-transition-new(root) {
  animation-duration: 320ms;
  animation-timing-function: cubic-bezier(0.25, 0.1, 0.25, 1);
}

/* One snapshot of the whole page: elements that name their own transition
   (the mobile settings pane slides) must not animate separately here. */
html.dn-private-vt * {
  view-transition-name: none !important;
}

@media (prefers-reduced-motion: reduce) {
  html.dn-private-vt::view-transition-old(root),
  html.dn-private-vt::view-transition-new(root) {
    animation: none;
  }
}
/* [Doona:END] */

/*
 * [Doona:FILE] - Glass material on the app's floating chrome
 * (DESIGN-ELEVATION.md «Glass»; tokens and the off-switch: elevation.css;
 * the class form for templates: .glass in components.css).
 *
 * Imported LAST in doona/index.css: it is unlayered and must win over the
 * opaque surfaces the earlier modules give these elements.
 *
 * Where, and only where, content scrolls underneath:
 *   thin     the floating scroll-to-bottom button (and the page toolbar
 *            chips, via the .glass classes in the templates)
 *   regular  menus (not the sidebar workspace/account menus), the mobile
 *            bottom nav, the private-mode pill, the imagine config popover
 *            when it is not inside the blurred prompt card
 *   thick    modal surfaces (centred on desktop, bottom sheets on phones)
 *   bar      the settings mobile top bar: an edge-to-edge bar tinted with
 *            the page colour
 * Not glass, because nothing scrolls under them: the mobile header, the
 * canvas toolbar and the chat composer (see DESIGN-ELEVATION.md «Glass»).
 * Toasts are glass too (inline style block in layouts/base.twig).
 *
 * Rules kept here, from apple-design §12 and the owner:
 *   - never glass on glass: a menu or popover INSIDE a glass host is opaque
 *     (a backdrop-filter inside a backdrop-filter only sees its host, and
 *     anything hanging outside the host would show the page unblurred);
 *   - nothing here transitions or animates backdrop-filter;
 *   - an element that moves every frame (a sheet being dragged or sliding)
 *     carries the opaque surface until it settles;
 *   - no lines: the specular highlight is a gradient + a blurred inner glow.
 */

/* ---- the recipe ----
   The sidebar's workspace and account menus (x-ref wsmenu / usermenu) are
   excluded by owner decision: they keep their own pre-redesign look, owned
   elsewhere — and they open over the opaque sidebar anyway. */
.menu:not([x-ref="wsmenu"], [x-ref="usermenu"]),
.doona-scroll-bottom-btn,
.bottom-nav,
.dn-private-pill,
.di-config-popover,
modal-element .modal {
  --color-content-dimmed: var(--glass-text-dimmed);
  background-color: var(--glass-tint);
  background-image:
    linear-gradient(var(--glass-state, transparent), var(--glass-state, transparent)),
    var(--glass-sheen);
  -webkit-backdrop-filter: var(--glass-filter);
  backdrop-filter: var(--glass-filter);
  box-shadow: var(--glass-shadow);
}

/* ---- tiers ---- */
.doona-scroll-bottom-btn {
  --glass-tint: var(--glass-thin-tint);
  --glass-filter: var(--glass-thin-filter);
  --glass-shadow: var(--glass-thin-shadow);
}

.menu:not([x-ref="wsmenu"], [x-ref="usermenu"]),
.bottom-nav,
.dn-private-pill,
.di-config-popover {
  --glass-tint: var(--glass-regular-tint);
  --glass-filter: var(--glass-regular-filter);
  --glass-shadow: var(--glass-regular-shadow);
}

modal-element .modal {
  --glass-tint: var(--glass-thick-tint);
  --glass-filter: var(--glass-thick-filter);
  --glass-shadow: var(--glass-thick-shadow);
}

/* ---- interaction: an overlay on the material, never a new background ---- */
@media (hover: hover) {
  .doona-scroll-bottom-btn:hover {
    --glass-state: var(--elev-hover);
  }
}

.doona-scroll-bottom-btn:active {
  --glass-state: var(--elev-pressed);
}

/* The chat composer is NOT glass: it sits in an opaque band with the
   model chips row above it, so nothing scrolls beneath it. Letting the
   transcript run under it would put the chips over text; a glass composer
   needs the chips inside it first (follow-up). */

/* ---- bars: page-tinted, edge to edge ----
   Behind @supports: color-mix() with var() in an engine that lacks it is
   invalid at computed time and would leave the bar transparent. */
@supports (color: color-mix(in srgb, red 50%, transparent)) {
@media (max-width: 1023.98px) {
  .settings-topbar {
    background-color: color-mix(in srgb, var(--color-main) 84%, transparent);
    -webkit-backdrop-filter: var(--glass-regular-filter);
    backdrop-filter: var(--glass-regular-filter);
  }

  /* Its fade below the bar matches the bar's alpha (was 72%: a step). */
  .settings-topbar::after {
    background: linear-gradient(to bottom, color-mix(in srgb, var(--color-main) 84%, transparent), transparent);
  }

  html.glass-off .settings-topbar {
    background-color: var(--color-main);
  }

  html.glass-off .settings-topbar::after {
    content: none;
  }
}
}

/* ---- the modal scrim dims, it does not blur ----
   The surface on top is now the material; a blurred scrim under it would be
   a second backdrop-filter stacked under the first (glass on glass) and a
   full-viewport blur on every open. Apple sheets dim the page. */
modal-element,
modal-element::before {
  -webkit-backdrop-filter: none !important;
  backdrop-filter: none !important;
}

/* ---- motion: no live blur while a surface moves ----
   Desktop modals only scale for a moment on an outside click; restrict
   their transition list so a theme flip can never interpolate the blur
   (transition-all would). Phone sheets slide 320ms and can be dragged: they
   keep the opaque tier until they have settled, then switch — a discrete
   step on the delay, not an animation. */
@media (width >= 48rem) {
  modal-element .modal {
    transition-property: transform, translate, scale, opacity, visibility;
  }
}

@media (width < 48rem) {
  modal-element .modal {
    --glass-tint: var(--elev-surface-3);
    --glass-filter: none;
    transition:
      translate var(--sheet-duration) var(--sheet-ease),
      background-color 0s linear 0s,
      -webkit-backdrop-filter 0s linear 0s,
      backdrop-filter 0s linear 0s;
  }

  modal-element.open:not([data-sheet-dragging]) .modal {
    --glass-tint: var(--glass-thick-tint);
    --glass-filter: var(--glass-thick-filter);
    transition-delay: 0s, var(--sheet-duration), var(--sheet-duration), var(--sheet-duration);
  }
}

/* ---- never glass on glass ----
   A menu or popover rendered inside another backdrop-filtered host (a menu
   inside a modal; the imagine/video/music config popover inside the
   blurred .di-form-card) is the opaque raised surface: its backdrop would
   only be the host. */
:is(modal-element .modal, .bottom-nav, .di-form-card, .glass) :is(.menu, .di-config-popover) {
  --glass-tint: var(--elev-surface-2);
  --glass-filter: none;
  --glass-sheen: none;
}

/* ---- group separators inside glass menus ----
   The one sanctioned line (iOS context-menu groups) must read on a
   translucent surface: a translucent ink, not the opaque line colour. */
.menu:not([x-ref="wsmenu"], [x-ref="usermenu"]) {
  --elev-separator: var(--glass-separator);
}

/* ---- older blurs, made to honour the off switch ----
   Pre-existing materials that predate the tokens: with glass off they lose
   the blur and take an opaque surface, so they stay legible without it. */
html.glass-off .di-form-card {
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  background: var(--elev-surface-1);
}

html.glass-off .di-form-card:focus-within {
  background: var(--elev-surface-2);
}

html.glass-off .doona-quota-pop__panel {
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  background: var(--elev-surface-2);
}

@media (prefers-reduced-transparency: reduce) {
  .di-form-card {
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
    background: var(--elev-surface-1);
  }
}

/* ---- phone sheets that drag: opaque ----
   The imagine/video/music config popover becomes a draggable bottom sheet
   on phones; it snaps back and slides out by translate after the drag
   attribute is gone, so it never gets a live blur there. */
@media (max-width: 640px) {
  .di-config-popover[x-sheet-drag],
  .di-form-card .di-config-popover[x-sheet-drag] {
    --glass-tint: var(--elev-surface-3);
    --glass-filter: none;
  }
}

/* ---- hover text on interactive glass ----
   The unlayered light-mode `.text-content-dimmed` colour beat every hover
   colour on the toolbar chips; on a pointer, the hovered chip's label goes
   to the content colour. */
@media (hover: hover) {
  html[data-mode] .glass-interactive:hover {
    color: var(--color-content);
  }
}
