/* ------------------------------------------------------------------ *
 * Portal shell fixes. nix.css was written for the standalone landing
 * documents where <body> directly holds .site-head + .page; Odoo's
 * website.layout wraps everything in one extra #wrapwrap div, so that
 * div has to become transparent to the flex column nix.css expects,
 * or the locked body (overflow:hidden) leaves the page unscrollable.
 * ------------------------------------------------------------------ */

#wrapwrap {
  display: flex;
  flex-direction: column;
  height: 100%;
  min-height: 0;
}

/* .page--flow switches the scroller to display:block, so flex centering
   is gone: center the content column with auto margins instead. */
#wrapwrap > main.page > * {
  width: 100%;
  max-width: 42rem;
  margin-left: auto;
  margin-right: auto;
}

/* The landing reveals these with body.is-ready once its preloader hands
   over; the portal has no preloader, so nothing would ever set the class
   and the brand + copyright sit at opacity:0 forever. */
#wrapwrap .site-head__brand,
#wrapwrap .foot__line {
  opacity: 1;
  transform: none;
}

/* ------------------------------------------------------------------ *
 * Theme parity. Odoo's own stylesheets load after nix.css and repaint
 * body white, so dark mode turned the logo white (nix.css inverts it)
 * on a page that never went dark — an invisible brand. Everything here
 * reads the nix.css variables, which already flip at the html level for
 * both the explicit data-theme and the OS prefers-color-scheme case, so
 * no rule needs a per-theme copy. Specificity (html body, #wrapwrap)
 * outranks the bootstrap rules regardless of load order.
 * ------------------------------------------------------------------ */

html body {
  background: var(--nix-paper);
  color: var(--nix-text);
  font-family: var(--font-sans);
}

#wrapwrap {
  background: var(--nix-paper);
  color: var(--nix-text);
}

#wrapwrap .form-control,
#wrapwrap .list-group-item,
#wrapwrap .o_show_password {
  background: var(--nix-surface);
  color: var(--nix-text);
  border-color: var(--nix-rule);
}

#wrapwrap .form-control::placeholder {
  color: var(--nix-text-soft);
}

/* bootstrap declares this one !important, so matching it is the only way */
#wrapwrap .text-muted {
  color: var(--nix-text-soft) !important;
}

/* Email + password only: the '- or -', Odoo.com OAuth and passkey block. */
#wrapwrap .o_login_auth {
  display: none;
}

/* Odoo ships the form d-none and lets the user-switch owl component
   reveal it once the JS bundle arrives — an empty card in the meantime.
   No remembered-user switch on this portal, so the form just shows.
   Scoped to any form in the card: login, reset password, signup.
   !important against !important: bootstrap's d-none carries one too. */
#wrapwrap .oe_website_login_container form {
  display: block !important;
  width: 100%;
}

#wrapwrap owl-component:empty {
  display: none;
}

/* Full width of the card for every row of every card form. */
#wrapwrap .oe_website_login_container form .mb-3,
#wrapwrap .oe_website_login_container form .o_caps_lock_warning,
#wrapwrap .oe_website_login_container form .input-group,
#wrapwrap .oe_website_login_container form .form-control,
#wrapwrap .oe_website_login_container form .oe_login_buttons,
#wrapwrap .oe_website_login_container form .btn-primary {
  width: 100%;
}

/* 'Back to Login' under the button: centered, in the text color. On the
   reset page it is a bare <a> in a justify-content-between row (bootstrap
   utility, shipped !important — matching it is the only way). */
#wrapwrap .oe_login_buttons .btn-link,
#wrapwrap .oe_login_buttons a {
  display: block;
  margin-top: 8px;
  text-align: center;
  color: var(--nix-text);
  text-decoration: none;
  font-size: 12px;
}

#wrapwrap .oe_login_buttons .d-flex {
  justify-content: center !important;
}

/* One signup door, ours. If Free sign up is switched on, auth_signup adds
   its own 'Don't have an account?' next to the permanent Create account. */
#wrapwrap .oe_login_buttons a.btn-link:not(.nix-login__signup) {
  display: none;
}

/* No focus dress-up: the fields keep their fill, nothing glows. */
#wrapwrap .form-control:focus,
#wrapwrap .form-control:focus-visible,
#wrapwrap .btn:focus,
#wrapwrap .btn:focus-visible {
  outline: none;
  box-shadow: none;
  border: none;
}

#wrapwrap .form-control:focus {
  background: var(--fill);
  color: var(--nix-text);
}

/* Autofill paints its own tint (the violet wash on the email field);
   inset-shadow over it is the one mechanism browsers honour. */
#wrapwrap input:-webkit-autofill,
#wrapwrap input:-webkit-autofill:hover,
#wrapwrap input:-webkit-autofill:focus {
  -webkit-box-shadow: 0 0 0 1000px var(--nix-surface) inset;
  -webkit-text-fill-color: var(--nix-text);
  caret-color: var(--nix-text);
}

/* Except inside the input group, where the field shares the row with the
   eye button and flexes instead. */
#wrapwrap .input-group .form-control {
  width: auto;
  flex: 1;
}

@media (max-width: 600px) {
  #wrapwrap > main.page > .oe_website_login_container {
    padding: 24px;
  }
}

/* ------------------------------------------------------------------ *
 * Sign-in card, after Agent Base's login: one 360px panel centered in
 * the viewport, a masked mark, a light display title, fill fields with
 * no hairline, and an ink button that flips contrast with the theme.
 * --fill is the one derived tone: a small step of text over surface,
 * which lands close to Agent Base's fill in both themes.
 * ------------------------------------------------------------------ */

#wrapwrap:not(.nix-shell) > main.page {
  display: flex;
  flex-direction: column;
  justify-content: center;
}

/* The child selector matters: the generic main.page > * rule above is
   (1,1,1) and this must outrank its 42rem/width to actually be a card. */
#wrapwrap > main.page > .oe_website_login_container {
  --fill: color-mix(in srgb, var(--nix-text) 7%, var(--nix-surface));
  width: 100%;
  max-width: 360px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 32px;
  background: var(--nix-surface);
  border-radius: 16px;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.06), 0 12px 32px rgba(0, 0, 0, 0.08);
}

#wrapwrap .nix-login__title {
  margin: 0 0 24px;
  font-size: 26px;
  font-weight: 300;
  text-align: center;
  color: var(--nix-text);
}

/* One label voice on every card: login uses .form-label, the reset and
   signup forms use .col-form-label — same size, color and spacing. */
#wrapwrap .form-label,
#wrapwrap .col-form-label {
  margin-bottom: 8px;
  padding: 0;
  font-size: 16px;
  line-height: 1.4;
  color: var(--nix-text);
}

#wrapwrap .form-control,
#wrapwrap .o_show_password {
  background: var(--fill);
  border: none;
  border-radius: 8px;
  padding: 12px;
  font-size: 13px;
}

#wrapwrap .input-group .form-control {
  border-top-right-radius: 0;
  border-bottom-right-radius: 0;
}

#wrapwrap .o_show_password {
  border-top-left-radius: 0;
  border-bottom-left-radius: 0;
  color: var(--nix-text-soft);
}

#wrapwrap .btn-primary {
  margin-top: 12px;
  padding: 12px;
  font-size: 13px;
  background: var(--nix-ink);
  color: var(--nix-on-ink);
  border: none;
  border-radius: 8px;
}

#wrapwrap .btn-primary:hover {
  background: var(--nix-ink-soft);
  color: var(--nix-on-ink);
}

#wrapwrap .btn-link {
  font-size: 12px;
  color: var(--nix-text-soft);
  text-decoration: none;
}

#wrapwrap .btn-link:hover {
  color: var(--nix-text);
}

#wrapwrap .list-group {
  gap: 8px;
}

#wrapwrap .list-group-item {
  background: var(--fill);
  border: none;
  border-radius: 8px;
  padding: 12px;
  font-size: 13px;
  color: var(--nix-text);
}

#wrapwrap .list-group-item:hover {
  background: color-mix(in srgb, var(--nix-text) 12%, var(--nix-surface));
}

/* ------------------------------------------------------------------ *
 * The drop, beside the card. nix.css positions .assist__orb absolutely
 * for the guide overlay; here it is an ordinary flex sibling, shown only
 * when there is room for a second column — never stacked above the form.
 * ------------------------------------------------------------------ */

/* Odoo leaves empty editor drop-zones around the form; as flex items in
   the row layout they would claim column space. */
#wrapwrap .oe_structure:empty {
  display: none;
}

/* ------------------------------------------------------------------ *
 * The app shell, for signed-in pages: a 64px rail (logo, nav, account)
 * beside one rounded panel that holds the page — the same anatomy as
 * Agent Base's dashboard. Public pages keep the landing header.
 * ------------------------------------------------------------------ */

#wrapwrap.nix-shell {
  flex-direction: row;
  gap: 8px;
  padding: 8px;
}

#wrapwrap.nix-shell > main.page {
  background: color-mix(in srgb, var(--nix-text) 4%, var(--nix-paper));
  border-radius: 16px;
  /* One measure all round, and small: the title's center stays level
     with the rail logo's, and the content hugs the panel's left edge. */
  padding: 12px;
}

/* The one-line landing footer has no seat in the shell. */
#wrapwrap.nix-shell .foot {
  display: none;
}

/* The app's rail, measure for measure: 58px wide, radius 20, 12px
   vertical padding, an 8px rhythm; tiles are 34px at radius 8. */
.nix-rail {
  width: 58px;
  flex: none;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  padding: 12px 0;
  background: color-mix(in srgb, var(--nix-text) 4%, var(--nix-paper));
  border-radius: 20px;
}

.nix-rail__logo {
  line-height: 0;
}

/* Stacked clock, the app's rail-clock: hour over minute, minutes fainter,
   on its own tile-sized surface so the rail reads as one column of objects. */
.nix-rail__clock {
  flex: none;
  width: 34px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  padding: 8px 0;
  background: color-mix(in srgb, var(--nix-text) 7%, transparent);
  border-radius: 8px;
  font-size: 12px;
  line-height: 1;
  color: var(--nix-text-soft);
  font-variant-numeric: tabular-nums;
  user-select: none;
}

.nix-rail__clock-m {
  color: color-mix(in srgb, var(--nix-text-soft) 60%, transparent);
}

/* A sibling, not a border on the clock — the app's rail-sep: tile-wide,
   one pixel, dividing the clock from the list without belonging to either. */
.nix-rail__sep {
  flex: none;
  width: 34px;
  height: 1px;
  background: color-mix(in srgb, var(--nix-text) 7%, transparent);
}

.nix-rail__nav {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
}

.nix-rail__item {
  flex: none;
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border-radius: 8px;
  color: var(--nix-text-soft);
}

.nix-rail__item:hover {
  color: var(--nix-text);
  background: color-mix(in srgb, var(--nix-text) 7%, transparent);
}

.nix-rail__item svg {
  width: 20px;
  height: 20px;
}

.nix-rail__foot {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
}

.nix-rail__foot {
  position: relative;
}

.nix-rail__avatar {
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  border: none;
  padding: 0;
  background: var(--nix-ink);
  color: var(--nix-on-ink);
  font-size: 12px;
  cursor: pointer;
}

/* Avatar popover: opens rightward from the rail's foot. */
.nix-popover {
  position: absolute;
  left: calc(100% + 12px);
  bottom: 0;
  min-width: 170px;
  display: none;
  flex-direction: column;
  padding: 6px;
  border-radius: 12px;
  background: color-mix(in srgb, var(--nix-text) 6%, var(--nix-paper));
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.35);
  z-index: 90;
}

.nix-popover[data-state="open"] {
  display: flex;
}

.nix-popover__item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 10px 12px;
  border: none;
  border-radius: 8px;
  background: transparent;
  color: var(--nix-text);
  font-size: 13px;
  text-align: left;
  text-decoration: none;
  cursor: pointer;
}

.nix-popover__item:hover {
  background: color-mix(in srgb, var(--nix-text) 8%, transparent);
  color: var(--nix-text);
  text-decoration: none;
}

.nix-popover__label {
  display: flex;
  align-items: center;
  gap: 10px;
}

.nix-popover__label svg {
  width: 16px;
  height: 16px;
  color: var(--nix-text-soft);
}

.nix-popover__item:hover .nix-popover__label svg {
  color: var(--nix-text);
}

/* The dot indicator inside the Theme row is a passive span — the row is
   the button — but it keeps nix.css's fills-when-dark treatment. */
.nix-popover .theme-toggle {
  display: inline-block;
  pointer-events: none;
}

/* One shared tooltip, fixed to the viewport, the app's ds-tooltip: an
   ink bubble to the right of whichever rail trigger the pointer is on. */
.nix-tooltip {
  position: fixed;
  z-index: 95;
  transform: translateY(-50%);
  white-space: nowrap;
  pointer-events: none;
  opacity: 0;
  background: var(--nix-ink);
  color: var(--nix-on-ink);
  border-radius: 8px;
  padding: 4px 8px;
  font-size: 12px;
  transition: opacity 120ms ease-out;
}

.nix-tooltip.is-open {
  opacity: 1;
}

/* Dark logo ink flips with the theme, same rule the landing uses. */
html[data-theme="dark"] .nix-rail__logo img {
  filter: brightness(0) invert(1);
}

@media (prefers-color-scheme: dark) {
  html:not([data-theme="light"]) .nix-rail__logo img {
    filter: brightness(0) invert(1);
  }
}

/* ------------------------------------------------------------------ *
 * Forms inside the shell panel (/my/account and friends): the same
 * fill fields and ink button the sign-in card wears, and none of the
 * website theme's accent color on buttons or links.
 * ------------------------------------------------------------------ */

#wrapwrap.nix-shell .form-control,
#wrapwrap.nix-shell .form-select {
  background: color-mix(in srgb, var(--nix-text) 7%, var(--nix-paper));
  color: var(--nix-text);
  border: none;
  border-radius: 8px;
  padding: 12px;
  font-size: 13px;
}

#wrapwrap.nix-shell .form-select {
  padding-right: 32px;
}

#wrapwrap.nix-shell .btn-primary {
  background: var(--nix-ink);
  color: var(--nix-on-ink);
  border: none;
  border-radius: 8px;
  padding: 10px 16px;
  font-size: 13px;
}

#wrapwrap.nix-shell .btn-primary:hover {
  background: var(--nix-ink-soft);
  color: var(--nix-on-ink);
}

#wrapwrap.nix-shell .btn-secondary,
#wrapwrap.nix-shell .btn-light,
#wrapwrap.nix-shell .btn-outline-primary,
#wrapwrap.nix-shell .btn-outline-secondary,
#wrapwrap.nix-shell .btn-link {
  background: color-mix(in srgb, var(--nix-text) 7%, var(--nix-paper));
  color: var(--nix-text);
  border: none;
  border-radius: 8px;
  padding: 10px 16px;
  font-size: 13px;
  text-decoration: none;
}

#wrapwrap.nix-shell main.page a {
  color: var(--nix-text);
}

/* Belt to the template's braces: if a build still renders the details
   sidebar (avatar, email, Edit information) or its offcanvas twin, it
   stays invisible and the content column takes the row. */
#wrapwrap.nix-shell .row > .d-lg-flex.col-lg-4,
#wrapwrap.nix-shell #accountOffCanvas,
#wrapwrap.nix-shell [data-bs-target="#accountOffCanvas"] {
  display: none !important;
}

#wrapwrap.nix-shell .o_portal_content {
  width: 100%;
}

/* Inside the shell the panel is the page: content hangs off its top-left
   like the app's Agents view, not down a centered website column. The
   42rem column, the login's vertical centering and bootstrap's .container
   all step aside — and the rows lose their negative margins, which were
   pushing cards past the panel's right edge once the container was gone. */
#wrapwrap.nix-shell > main.page {
  justify-content: flex-start;
}

#wrapwrap.nix-shell > main.page > * {
  max-width: none;
  margin: 0;
}

#wrapwrap.nix-shell .o_portal_wrap .row {
  margin-left: 0;
  margin-right: 0;
}

/* The rail already navigates everywhere the cards pointed: the account
   home keeps only its title. */
#wrapwrap.nix-shell .o_portal_docs {
  display: none;
}

/* Bootstrap indents the cards through three layers of column padding
   (content col 15px, category 4, card 4) while the title sits at the
   panel edge. The category becomes a grid of tiles instead — flush
   left with the title, the way the app lays its tiles. */
#wrapwrap.nix-shell .o_portal_wrap .wrapper,
#wrapwrap.nix-shell .o_portal_wrap .o_portal_content {
  padding-left: 0;
  padding-right: 0;
}

#wrapwrap.nix-shell .o_portal_category {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
  gap: 12px;
  padding: 0;
  margin: 24px 0 0;
}

#wrapwrap.nix-shell .o_portal_index_card {
  padding: 0;
  width: auto;
  max-width: none;
}

/* Not this portal's business either: orders, invoices and addresses
   stay off the account home. */
#wrapwrap.nix-shell .o_portal_index_card:has(a[href^="/my/orders"]),
#wrapwrap.nix-shell .o_portal_index_card:has(a[href^="/my/invoices"]),
#wrapwrap.nix-shell .o_portal_index_card:has(a[href^="/my/addresses"]) {
  display: none;
}

/* /my/account's address form: unconstrained it spreads col-lg-8 across
   the whole panel and pushes Zip off the edge. One 44rem column, the
   outer col flattened, and the form's own rows keep their bootstrap
   gutters so paired fields (City/Zip) still sit side by side flush. */
#wrapwrap.nix-shell .o_customer_address_fill {
  max-width: 44rem;
}

#wrapwrap.nix-shell .o_customer_address_fill > .row > [class*="col-"] {
  width: 100%;
  padding: 0;
}

#wrapwrap.nix-shell .o_customer_address_fill form .row {
  margin-left: -12px;
  margin-right: -12px;
}

/* Not the portal's business: VAT and the invoice-delivery preferences
   (Receive invoices / Electronic format) stay out of the Profile form.
   The invoice rows carry m-0, which keeps :has() off the form's own
   outer row. */
#wrapwrap.nix-shell #div_vat,
#wrapwrap.nix-shell .row.m-0:has(select[name="invoice_sending_method"]),
#wrapwrap.nix-shell .row.m-0:has(select[name="invoice_edi_format"]) {
  display: none;
}

/* The empty breadcrumb strip (o_portal container mt-3) sat above #wrap
   on the details page and pushed Profile below the other titles. */
#wrapwrap.nix-shell > main.page > .o_portal.mt-3 {
  display: none;
}

/* /my/security: password change only. Two-factor and passkeys stay out
   (their sections carry the ids of their own buttons in either state),
   the Go Back chip goes — the rail is the way around — and the header
   row loses its my-3 so the title sits level with the other pages'. */
#wrapwrap.nix-shell .o_portal_security_body section:has(#auth_totp_portal_enable),
#wrapwrap.nix-shell .o_portal_security_body section:has(#auth_totp_portal_disable),
#wrapwrap.nix-shell .o_portal_security_body section:has(#portal_passkey_add),
#wrapwrap.nix-shell .o_portal_security_body #totp_wizard_view,
#wrapwrap.nix-shell .o_portal_security_body a[title="Go Back"],
#wrapwrap.nix-shell .o_portal_security_body section[name="portal_deactivate_account"] {
  display: none;
}

#wrapwrap.nix-shell .o_portal_security_body > .d-flex.my-3 {
  margin: 0 0 24px !important;
}

#wrapwrap.nix-shell .o_portal_security_body {
  width: 100% !important;
  max-width: 44rem;
}

/* /my/payment_method: same seat as the rest. Its wrapper is a bare
   .wrap (not o_portal_wrap), the breadcrumb goes, the centered column
   docks left at 44rem, and the form's own 'Payment method' header
   dresses like the other page titles. */
#wrapwrap.nix-shell main.page > .wrap > .container {
  max-width: 100%;
  margin: 0;
  padding: 0;
}

#wrapwrap.nix-shell .wrap ol.breadcrumb {
  display: none;
}

#wrapwrap.nix-shell .wrap .row {
  margin: 0;
}

#wrapwrap.nix-shell .wrap .row.justify-content-center {
  justify-content: flex-start !important;
}

#wrapwrap.nix-shell .wrap .row.justify-content-center > [class*="col-"] {
  width: 100%;
  max-width: 44rem;
  padding: 0;
}

#wrapwrap.nix-shell .wrap p.h4 {
  margin: 0 0 24px !important;
  font-size: 26px;
  font-weight: 400;
  color: var(--nix-text);
}

#wrapwrap.nix-shell .o_portal_wrap .container {
  max-width: 100%;
  margin: 0;
  /* bootstrap's pt-3/pb-5 utilities ship !important */
  padding: 0 !important;
}

/* The page title, the app way: top-left, quiet weight, room below. */
#wrapwrap.nix-shell .o_portal_wrap h3 {
  /* my-3 is a bootstrap utility and ships !important */
  margin: 0 0 24px !important;
  font-size: 26px;
  font-weight: 400;
  color: var(--nix-text);
}

#wrapwrap.nix-shell .nix-devices {
  padding: 0;
}

#wrapwrap.nix-shell .nix-devices .nix-login__title,
#wrapwrap.nix-shell .nix-devices__plan,
#wrapwrap.nix-shell .nix-devices__empty {
  text-align: left;
}

#wrapwrap.nix-shell .nix-devices .nix-login__title {
  margin: 0 0 8px;
  font-weight: 400;
}

#wrapwrap.nix-shell .nix-devices__list {
  max-width: 42rem;
}

/* ------------------------------------------------------------------ *
 * /my/plan — the plans as tiles, the current one marked.
 * ------------------------------------------------------------------ */

#wrapwrap.nix-shell .nix-plans .nix-login__title {
  margin: 0 0 8px;
  font-weight: 400;
  text-align: left;
}

#wrapwrap.nix-shell .nix-plans__current {
  margin: 0 0 24px;
  color: var(--nix-text-soft);
}

/* The landing page's .ab-price family, copied verbatim from ab01's inline
   sheet (that page is standalone and never loads this file) with one
   change: the grid docks left under the title instead of centering. */
.ab-price {
  width: min(1000px, 100%);
  margin: 24px 0 0;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 12px;
  text-align: left;
}

.ab-price__card {
  background: rgba(128, 128, 128, 0.055);
  border-radius: 25px;
  padding: 26px 24px;
  display: flex;
  flex-direction: column;
  gap: 13px;
}

.ab-price__card--lead {
  background: var(--nix-ink);
  color: var(--nix-on-ink);
}

.ab-price__name {
  font-size: clamp(15px, 1.15vw, 17px);
  font-weight: 400;
  line-height: 1.35;
  letter-spacing: -0.01em;
  margin: 0;
}

.ab-price__fig {
  display: flex;
  align-items: baseline;
  gap: 8px;
  margin: 0;
  flex-wrap: wrap;
}

.ab-price__amount {
  font-size: 34px;
  font-weight: 300;
  line-height: 1;
  letter-spacing: -0.02em;
}

.ab-price__per {
  font-size: 12px;
  letter-spacing: 0.02em;
  color: var(--nix-text-soft);
}

.ab-price__text {
  font-size: 13px;
  color: var(--nix-text-soft);
  line-height: 1.5;
  margin: 0;
}

.ab-price__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 9px;
}

.ab-price__item {
  position: relative;
  padding-left: 18px;
  font-size: 13px;
  line-height: 1.5;
  color: var(--nix-text-soft);
}

.ab-price__item::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0.52em;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  border: 1px solid currentColor;
}

.ab-price__card--lead .ab-price__per,
.ab-price__card--lead .ab-price__text,
.ab-price__card--lead .ab-price__item {
  color: var(--nix-on-ink);
  opacity: 0.64;
}

.ab-price__cta,
.ab-price__cta-form {
  margin-top: auto;
  align-self: flex-start;
}

.ab-price__cta-form .ab-price__cta {
  margin-top: 0;
}

/* Bootstrap's own .btn loads after nix.css and washes the landing pills
   out to transparent; the landing look is re-asserted with the id in
   front so load order stops mattering. */
#wrapwrap .btn.ab-price__cta {
  display: inline-block;
  padding: 12px 28px;
  border: 0;
  border-radius: 999px;
  font-size: 14px;
  letter-spacing: 0.02em;
  line-height: 1.5;
}

#wrapwrap .btn--paper.ab-price__cta {
  background: var(--nix-paper);
  color: var(--nix-ink);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.22);
}

#wrapwrap .btn--paper.ab-price__cta:hover {
  background: var(--nix-paper);
  color: var(--nix-ink);
  transform: translateY(-1px);
}

/* Ink, not surface: on the dark card the surface pill vanished into its
   own ground. --nix-ink flips with the theme, so this is the white pill
   in dark mode and the dark one in light. */
#wrapwrap .btn--ghost.ab-price__cta {
  background: var(--nix-ink);
  color: var(--nix-on-ink);
  box-shadow: 0 1px 3px rgba(26, 26, 26, 0.14);
}

#wrapwrap .btn--ghost.ab-price__cta:hover {
  background: var(--nix-ink);
  color: var(--nix-on-ink);
  transform: translateY(-1px);
}

@media (max-width: 900px) {
  .ab-price {
    grid-template-columns: 1fr;
  }
}

.nix-plans__badge {
  font-size: 12px;
  color: var(--nix-text-soft);
}

.nix-plans__manage {
  margin-top: 24px;
}

.nix-plans__manage .btn {
  background: color-mix(in srgb, var(--nix-text) 7%, var(--nix-paper));
  color: var(--nix-text);
  border: none;
  border-radius: 8px;
  padding: 10px 16px;
  font-size: 13px;
}

/* ------------------------------------------------------------------ *
 * /my/devices — the account's installs. Same tones as the cards.
 * ------------------------------------------------------------------ */

#wrapwrap .nix-devices {
  padding: 48px 0;
}

#wrapwrap .nix-devices__plan {
  text-align: center;
  color: var(--nix-text-soft);
  margin: 0 0 32px;
}

#wrapwrap .nix-devices__row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 16px;
  margin-bottom: 8px;
  border-radius: 12px;
  background: var(--nix-surface);
}

#wrapwrap .nix-devices__meta {
  font-size: 12px;
  color: var(--nix-text-soft);
}

#wrapwrap .nix-devices__revoked {
  color: var(--nix-text-soft);
}

#wrapwrap .nix-devices__empty {
  text-align: center;
  color: var(--nix-text-soft);
}

#wrapwrap .nix-devices__revoke {
  background: color-mix(in srgb, var(--nix-text) 7%, var(--nix-surface));
  color: var(--nix-text);
  border: none;
  border-radius: 8px;
  padding: 8px 16px;
  font-size: 13px;
}

/* ------------------------------------------------------------------ *
 * The mobile gate. The shell is desktop-first and its mobile view is
 * still on the bench: under 768px the rail and panel step aside and one
 * card says so. Hidden everywhere else.
 * ------------------------------------------------------------------ */

.nix-mobile-gate {
  display: none;
}

@media (max-width: 767px) {
  #wrapwrap.nix-shell .nix-rail,
  #wrapwrap.nix-shell > main.page {
    display: none !important;
  }

  #wrapwrap.nix-shell .nix-mobile-gate {
    position: fixed;
    inset: 0;
    z-index: 100;
    display: grid;
    place-items: center;
    padding: 24px;
    background: var(--nix-paper);
  }

  .nix-mobile-gate__card {
    max-width: 320px;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 12px;
    padding: 32px;
    border-radius: 16px;
    text-align: center;
    background: color-mix(in srgb, var(--nix-text) 4%, var(--nix-paper));
  }

  .nix-mobile-gate__card h2 {
    margin: 0;
    font-size: 20px;
    font-weight: 400;
    color: var(--nix-text);
  }

  .nix-mobile-gate__card p {
    margin: 0;
    font-size: 14px;
    color: var(--nix-text-soft);
  }

  html[data-theme="dark"] .nix-mobile-gate__card img {
    filter: brightness(0) invert(1);
  }

  @media (prefers-color-scheme: dark) {
    html:not([data-theme="light"]) .nix-mobile-gate__card img {
      filter: brightness(0) invert(1);
    }
  }
}

/* On a phone the column keeps its order — card first, the drop below it. */
#wrapwrap > main.page > .nix-login-orb {
  position: relative;
  width: min(260px, 70vw);
  max-width: none;
  aspect-ratio: 1 / 1;
  margin: 32px auto 0;
  flex: none;
}

@media (min-width: 920px) {
  #wrapwrap:not(.nix-shell) > main.page {
    flex-direction: row;
    align-items: center;
    justify-content: center;
    gap: 72px;
  }
  #wrapwrap:not(.nix-shell) > main.page > .oe_website_login_container {
    margin: 0;
    flex: none;
  }
  #wrapwrap:not(.nix-shell) > main.page > .nix-login-orb {
    width: min(360px, 34vw);
    margin: 0;
  }
}

/* Clear the fixed header the same way the landing hero does. */
#wrapwrap > main.page {
  padding-top: calc(var(--head-h, 73px) + var(--space-4, 24px));
}

/* ── /my/support — the ticket door ─────────────────────────────────────────
   Everything reads the shell's own tokens, so both themes come free: the
   primary is the app's inverse pill (text-colour ground, paper text), the
   secondary and the fields are text-colour tints. Colours are pinned on
   both states because the shell styles bare links. */
#wrapwrap.nix-shell .nix-support__head { display: flex; align-items: center; justify-content: space-between; gap: 16px; }
#wrapwrap.nix-shell .nix-support__new,
#wrapwrap.nix-shell .nix-support__submit {
  display: inline-flex; align-items: center; justify-content: center;
  padding: 10px 18px; border: 0; border-radius: 12px; cursor: pointer;
  background: var(--nix-text);
  /* !important, con dolor: el shell pinta <a> con su propio color en una
     regla posterior de igual especificidad — sin esto el texto del pill
     invertido desaparece en reposo y sólo se ve en hover. */
  color: var(--nix-paper) !important;
  font-size: 14px; font-weight: 400; line-height: 1; text-decoration: none;
  transition: opacity 160ms ease;
}
#wrapwrap.nix-shell .nix-support__new:hover,
#wrapwrap.nix-shell .nix-support__submit:hover { opacity: 0.85; color: var(--nix-paper) !important; }
#wrapwrap.nix-shell .nix-support__cancel {
  display: inline-flex; align-items: center; justify-content: center;
  padding: 10px 18px; border-radius: 12px;
  background: color-mix(in srgb, var(--nix-text) 8%, transparent);
  color: var(--nix-text) !important;
  font-size: 14px; line-height: 1; text-decoration: none;
  transition: background 160ms ease;
}
#wrapwrap.nix-shell .nix-support__cancel:hover { background: color-mix(in srgb, var(--nix-text) 14%, transparent); color: var(--nix-text) !important; }
#wrapwrap.nix-shell .nix-support__actions { display: flex; align-items: center; justify-content: flex-end; gap: 10px; }
#wrapwrap.nix-shell .nix-support__field {
  width: 100%; padding: 14px 16px; border: 0; outline: none;
  border-radius: 12px;
  background: color-mix(in srgb, var(--nix-text) 6%, transparent);
  color: var(--nix-text); font: inherit;
}
#wrapwrap.nix-shell .nix-support__field::placeholder { color: var(--nix-text-soft); }
#wrapwrap.nix-shell .nix-support__field:focus { background: color-mix(in srgb, var(--nix-text) 10%, transparent); }
.nix-support__form { display: flex; flex-direction: column; gap: 12px; max-width: 560px; margin-top: 8px; }
.nix-support__body { resize: vertical; min-height: 120px; }
.nix-support__list { margin-top: 10px; display: flex; flex-direction: column; gap: 8px; max-width: 560px; }
#wrapwrap.nix-shell .nix-support__row {
  display: flex; justify-content: space-between; align-items: center; gap: 16px;
  padding: 12px 16px; border-radius: 12px;
  background: color-mix(in srgb, var(--nix-text) 5%, transparent);
  color: var(--nix-text) !important; text-decoration: none;
}
#wrapwrap.nix-shell .nix-support__row:hover { background: color-mix(in srgb, var(--nix-text) 9%, transparent); color: var(--nix-text) !important; }
.nix-support__stage { opacity: 0.6; font-size: 13px; white-space: nowrap; }
/* The ticket page is a chat session: bar on top, bubbles, composer under. */
#wrapwrap.nix-shell .nix-ticket { display: flex; flex-direction: column; min-height: calc(100vh - 96px); }
.nix-ticket__bar { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; margin-bottom: 18px; }
#wrapwrap.nix-shell .nix-ticket__back {
  justify-self: start; display: inline-flex; align-items: center; justify-content: center;
  width: 36px; height: 36px; border-radius: 10px;
  color: var(--nix-text) !important;
  background: transparent;
}
#wrapwrap.nix-shell .nix-ticket__back:hover { background: color-mix(in srgb, var(--nix-text) 12%, transparent); }
.nix-ticket__word { font-size: 17px; }
.nix-ticket__end { justify-self: end; display: inline-flex; align-items: center; gap: 12px; }
#wrapwrap.nix-shell .nix-ticket__infobtn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; border-radius: 999px;
  font-family: Georgia, serif; font-style: italic; font-size: 15px;
  color: var(--nix-text) !important;
  background: color-mix(in srgb, var(--nix-text) 8%, transparent);
}
#wrapwrap.nix-shell .nix-ticket__infobtn:hover,
#wrapwrap.nix-shell .nix-ticket__infobtn.is-on { background: color-mix(in srgb, var(--nix-text) 16%, transparent); }
.nix-ticket__thread { display: flex; flex-direction: column; gap: 10px; flex: 1; }
#wrapwrap.nix-shell .nix-ticket__bubble {
  max-width: 62%; padding: 12px 16px; border-radius: 16px;
  background: color-mix(in srgb, var(--nix-text) 6%, transparent);
  align-self: flex-start;
}
#wrapwrap.nix-shell .nix-ticket__bubble.is-mine {
  align-self: flex-end;
  background: color-mix(in srgb, var(--nix-text) 12%, transparent);
}
.nix-ticket__bubblebody p { margin: 0 0 6px; }
.nix-ticket__bubblebody p:last-child { margin: 0; }
.nix-ticket__bubblemeta { margin-top: 6px; font-size: 12px; opacity: 0.55; }
/* ONE pill: + | text | round send — the app's composer shape. */
#wrapwrap.nix-shell .nix-ticket__composer {
  display: flex; align-items: center; gap: 8px; margin-top: 18px;
  width: min(100%, 720px); margin-left: auto; margin-right: auto;
  padding: 6px 6px 6px 16px; border-radius: 999px;
  background: color-mix(in srgb, var(--nix-text) 6%, transparent);
}
#wrapwrap.nix-shell .nix-ticket__attach {
  display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px; flex: none; cursor: pointer;
  color: var(--nix-text-soft); border-radius: 999px;
}
#wrapwrap.nix-shell .nix-ticket__attach:hover { color: var(--nix-text); }
.nix-ticket__fileinput { display: none; }
#wrapwrap.nix-shell .nix-ticket__input {
  flex: 1; padding: 10px 4px; border: 0; outline: none;
  background: transparent; color: var(--nix-text); font: inherit;
}
#wrapwrap.nix-shell .nix-ticket__input::placeholder { color: var(--nix-text-soft); }
#wrapwrap.nix-shell .nix-ticket__send {
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; flex: none; border: 0; border-radius: 999px; cursor: pointer;
  background: var(--nix-text); color: var(--nix-paper) !important;
  transition: opacity 160ms ease;
}
#wrapwrap.nix-shell .nix-ticket__send:hover { opacity: 0.85; }
.nix-ticket__files { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 8px; }
#wrapwrap.nix-shell .nix-ticket__file {
  display: inline-flex; padding: 6px 12px; border-radius: 999px; font-size: 12px;
  background: color-mix(in srgb, var(--nix-text) 10%, transparent);
  color: var(--nix-text) !important; text-decoration: none;
}
#wrapwrap.nix-shell .nix-ticket__file:hover { background: color-mix(in srgb, var(--nix-text) 16%, transparent); }
.nix-ticket__pending { display: flex; flex-wrap: wrap; gap: 8px; width: min(100%, 720px); margin: 0 auto 10px; }
#wrapwrap.nix-shell .nix-ticket__filex {
  border: 0; background: transparent; cursor: pointer; padding: 0 0 0 6px;
  color: inherit; font-size: 14px; line-height: 1;
}
.nix-ticket__about { flex: 1; display: flex; align-items: flex-start; justify-content: center; padding-top: 6vh; }
#wrapwrap.nix-shell .nix-ticket__aboutcard {
  width: min(92%, 520px); display: flex; flex-direction: column; gap: 14px;
  padding: 22px 24px; border-radius: 16px;
  background: color-mix(in srgb, var(--nix-text) 5%, transparent);
}
.nix-ticket__aboutrow { display: flex; flex-direction: column; gap: 3px; font-size: 14px; }
.nix-ticket__aboutlabel { font-size: 12px; opacity: 0.55; letter-spacing: 0.04em; text-transform: uppercase; }
.nix-support__thread { display: flex; flex-direction: column; gap: 10px; max-width: 640px; margin: 16px 0; }
#wrapwrap.nix-shell .nix-support__msg {
  padding: 12px 16px; border-radius: 12px;
  background: color-mix(in srgb, var(--nix-text) 5%, transparent);
}
#wrapwrap.nix-shell .nix-support__msg.is-mine {
  background: color-mix(in srgb, var(--nix-text) 10%, transparent);
}
.nix-support__msg-head { display: flex; justify-content: space-between; gap: 12px; margin-bottom: 6px; font-size: 13px; opacity: 0.8; }
.nix-support__msg-body p { margin: 0 0 6px; }
.nix-support__msg-body p:last-child { margin: 0; }
