/* ===========================================================
   Arqia · Agente Financeiro e de Faturamento — design system
   Type: Montserrat (Galano Grotesque when licensed)
   Palette: docs/reference/brand/STYLE-GUIDE.md
   Accessibility: --ink and --sec clear WCAG AAA 7:1 on white AND
   on Alice blue; --ter clears AAA on white (the panels) and AA on
   the tinted grounds. Vivid brand colors (--*-ico) are fills and
   dots only, never text: they fail AA as text. The focus ring and
   form-field borders clear the 3:1 non-text floor. Guarded by
   billing_validation/tests/web/test_color_contrast.py
   =========================================================== */
/* The UA sheet's `[hidden]{display:none}` is beaten on origin by ANY author
   rule that sets `display`, so an element carrying the attribute stayed on
   the page whenever a component gave it a display. `!important` is what the
   UA rule needed all along. Global and first on purpose: it is a reset. */
[hidden]{display:none!important}

:root{
  /* The page ground: the login screen's gradient with every stop taken a
     quarter of the way to white. It is painted once, over the first viewport,
     and its outer stop IS --bg-base, which carries on below it: a long page
     never shows a band where the tint ends. */
  --bg:radial-gradient(135% 90% at 50% -10%, #F2EDFB 0%, #F8F6FD 46%, #FCFBFE 100%);
  --bg-base:#FCFBFE;
  --surface:#fff; --sunken:#E9F0F3;

  /* Text ramp. --ink and --sec are AAA (7:1) on white and on Alice blue;
     --ter is AAA on white and AA on the tinted grounds. --ter is greyer than
     --sec rather than much lighter, so the ramp keeps three steps without
     dropping a caption below 7:1 on a panel. */
  --ink:#3D2F7F; --sec:#504582; --ter:#5A5379;
  /* Placeholder text: lighter than a typed value so an empty field never
     reads as filled, and still above AA. */
  --placeholder:#6E639F;

  /* non-text only: borders, dividers, decorative glyphs */
  --icon-muted:#8E88A3;
  --line:rgba(61,47,127,.12); --line-2:rgba(61,47,127,.07);
  /* The boundary of a form control. A field has to be findable by its edge
     (WCAG 1.4.11), and --line is 1.3:1, so controls get their own 3:1 border. */
  --field-line:#8E88A3;
  /* Keyboard focus ring: accent on light grounds, white on the nav gradient. */
  --focus:#662DFF;
  --row-hover:#F6F4FC;

  --accent:#662DFF; --accent-soft:#F1ECFE; --accent-soft-2:#E6DBFD;
  --accent-strong:#5420D9;
  --expanded:#FBFAFF;

  /* status: -ico is the vivid brand color (dot/icon), the base is the label */
  --ok:#0B6B41;   --ok-ico:#0AE587;   --ok-bg:#E8FBF3;
  --warn:#7A5B00; --warn-ico:#FFC700; --warn-bg:#FFF6DC;
  --bad:#D90A66;  --bad-ico:#FF0033;  --bad-bg:#FFF2F6;
  /* Body text on --bad-bg (and error text next to a field). The --bad label
     colour is tuned for chips and goes muddy in a paragraph, so prose gets its
     own darker ink. */
  --bad-ink:#8A2050;
  --neu:#5F5A70;  --neu-ico:#8E88A3;  --neu-bg:#F1F2F5;
  --ressalva:#0F6A54; --ressalva-ico:#18B88A; --ressalva-bg:#E6F7F1;
  --bloqueio:#7A0B2E; --bloqueio-ico:#A80B2E; --bloqueio-bg:#FBE9EE;

  /* gradient #1 — logo and hero decoration ONLY (its red end is 3.96:1) */
  --grad-brand:linear-gradient(90deg,#FF0033 0%,#D90A66 35%,#662DFF 100%);
  /* hero fill — gradient #1 MIRRORED so left-aligned text sits on the
     indigo/rose end (5.02:1+); the red end lands under the ring motif. */
  --grad-hero:linear-gradient(90deg,#662DFF 0%,#D90A66 65%,#FF0033 100%);
  /* gradient #2 — nav bar; white text is safe end to end (5.02 → 10.99) */
  --grad-nav:linear-gradient(90deg,#D90A66 0%,#3D2F7F 100%);

  /* Nav bar height. A token because the top-right ring set centres on the
     corner of the content area, this far down from the viewport top. */
  --bar-h:72px;
  /* Page gutter and the content measure every screen shares. */
  --gutter:40px;
  --page-w:1360px;
  --r:12px;
  --r-sm:8px;
  /* Control height: 44px is the WCAG 2.5.5 target for primary actions, and
     every control shares it so a toolbar row lines up. */
  --control-h:44px;
  --control-h-sm:32px;
  /* Card elevation: a contact shadow plus one soft ambient layer, tinted with
     the brand indigo (a neutral shadow on this ground reads as dirty grey). */
  --shadow:0 1px 2px rgba(61,47,127,.05),0 4px 14px -6px rgba(61,47,127,.10);

  /* Type scale. One step per role, used by every page. */
  --fs-h1:28px; --fs-h2:18px; --fs-h3:15px; --fs-body:14px; --fs-sm:13px; --fs-xs:12px;
}
*{box-sizing:border-box}
html,body{margin:0}
/* Always reserve the scrollbar gutter so centered content does not shift
   between pages that scroll and pages that don't. */
html{scrollbar-gutter:stable;background:var(--bg-base);-webkit-text-size-adjust:100%}
body{
  font-family:"Galano Grotesque","Montserrat",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;
  /* The tint covers the first viewport and fades into --bg-base, which is
     both its outer stop and the colour below it. Not `fixed`: a fixed ground
     is painted per viewport (and ignored by iOS), which is what left a hard
     band on long pages and in full-page captures. */
  background:var(--bg) top center / 100% 100vh no-repeat var(--bg-base);
  min-height:100vh;
  color:var(--ink);font-size:var(--fs-body);line-height:1.5;letter-spacing:-.005em;
  -webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;
  overflow-wrap:break-word;
}
a{color:inherit;text-decoration:none}
img,svg{max-width:100%}
.mono{font-variant-numeric:tabular-nums;font-feature-settings:"tnum"}
.sp{flex:1}
/* Tertiary text ramp as a utility class. `.muted` is the contract name. */
.ter,.muted{color:var(--ter)}

/* ---- headings: one scale for every page ---- */
:where(main) h1{font-size:var(--fs-h1);font-weight:700;letter-spacing:-.025em;line-height:1.15}
:where(main) h2{font-size:var(--fs-h2);font-weight:700;letter-spacing:-.015em;line-height:1.3}
:where(main) h3{font-size:var(--fs-h3);font-weight:700;letter-spacing:-.01em;line-height:1.35}
/* A heading that receives focus programmatically (after a menu swap, or a
   skip link) is not a control: it should be announced, not ringed. */
[tabindex="-1"]:focus{outline:none}

/* ---- keyboard focus: one visible ring everywhere ----
   2px solid, offset off the element, 6.2:1 against white. Anything that
   paints its own ring must keep it at least this visible. */
:focus-visible{outline:2px solid var(--focus);outline-offset:2px}
.bar :focus-visible{outline-color:#fff}

/* ---- skip link: first stop of the Tab order ---- */
.skip{position:absolute;left:16px;top:-200px;z-index:200;display:inline-flex;align-items:center;
  min-height:var(--control-h);padding:0 18px;border-radius:var(--r-sm);background:var(--surface);
  color:var(--ink);font-weight:700;box-shadow:0 4px 14px rgba(61,47,127,.25)}
.skip:focus{top:12px;outline:2px solid var(--focus);outline-offset:2px}

/* ---- top bar ---- */
.bar{position:sticky;top:0;z-index:50;display:flex;align-items:center;gap:28px;
  padding:0 var(--gutter);height:var(--bar-h);background:var(--grad-nav);color:#fff;
  border-bottom:1px solid rgba(255,255,255,.10)}
.bar-logo{display:flex;align-items:center;flex:none;min-height:44px;border-radius:6px}
.logo-img{height:32px;width:auto;display:block}
.tabs{display:flex;align-items:stretch;gap:2px;height:100%;min-width:0}
/* All tabs are solid white: on --grad-nav's rose end even .9-alpha white is
   only 4.22:1, so an inactive tab cannot be dimmed and stay legible. The
   active state is weight + the bar under it, and `aria-current` for AT. */
.tabs a{position:relative;display:inline-flex;flex-direction:column;justify-content:center;
  align-items:center;padding:0 12px;font-weight:500;color:#fff;font-size:14px;white-space:nowrap}
/* Reserves the bold width (data-label = the visible text), so the active
   item never pushes its neighbours when the menu swaps screens. */
.tabs a::before{content:attr(data-label);font-weight:700;height:0;overflow:hidden;visibility:hidden}
.tabs a.on,.tabs a[aria-current="page"]{font-weight:700}
.tabs a::after{content:"";position:absolute;left:12px;right:12px;bottom:0;height:3px;
  border-radius:3px 3px 0 0;background:transparent;transition:background-color .15s ease}
.tabs a:hover::after{background:rgba(255,255,255,.45)}
.tabs a.on::after,.tabs a[aria-current="page"]::after{background:#fff}
.tabs a:focus-visible{outline-offset:-6px}
.tabs .n{margin-left:6px;background:var(--bad);color:#fff;font-size:12px;font-weight:700;min-width:16px;height:16px;padding:0 4px;border-radius:999px;display:grid;place-items:center;align-self:center}
.bar-user{display:flex;align-items:center;gap:8px;flex:none}
.usr{display:flex;align-items:center;gap:9px;color:#fff;font-size:13px;font-weight:500;white-space:nowrap}
.av{width:30px;height:30px;border-radius:50%;background:rgba(255,255,255,.18);color:#fff;
  display:grid;place-items:center;font-weight:700;font-size:12px;flex:none}
.bar-out{display:inline-flex;align-items:center;min-height:44px;padding:0 12px;border-radius:var(--r-sm);
  color:#fff;font-size:13px;font-weight:600}
.bar-out:hover{text-decoration:underline;text-underline-offset:3px}
/* The disclosure that holds the menu on narrow screens. */
.bar-menu{display:none;align-items:center;gap:8px;min-height:44px;padding:0 14px;
  border:1px solid rgba(255,255,255,.45);border-radius:var(--r-sm);background:transparent;
  color:#fff;font:inherit;font-size:14px;font-weight:600;cursor:pointer}
.bar-menu:hover{background:rgba(0,0,0,.12)}
.bar-menu .ico-close{display:none}
.bar-menu[aria-expanded="true"] .ico-open{display:none}
.bar-menu[aria-expanded="true"] .ico-close{display:inline}
@media (max-width:1100px){
  .bar{gap:16px;padding:0 24px}
  .tabs a{padding:0 9px}
  .tabs a::after{left:9px;right:9px}
  /* The name stays for assistive technology; the initials stand in for it. */
  .usr-name{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
}
@media (max-width:960px){
  :root{--bar-h:60px;--gutter:16px}
  .bar{gap:10px;padding:0 var(--gutter)}
  .logo-img{height:26px}
  .bar-menu{display:inline-flex}
  .bar-user{gap:2px}
  /* With JS the menu is a panel the button opens, under the bar. */
  .bar.js-menu .tabs{display:none}
  .bar.js-menu.nav-open .tabs{display:flex;flex-direction:column;align-items:stretch;gap:0;
    position:absolute;left:0;right:0;top:100%;height:auto;max-height:calc(100vh - var(--bar-h));
    overflow-y:auto;padding:6px 0;background:var(--surface);border-bottom:1px solid var(--line);
    box-shadow:0 10px 18px -8px rgba(61,47,127,.28)}
  .bar.js-menu.nav-open .tabs a{align-items:flex-start;min-height:48px;padding:0 var(--gutter) 0 calc(var(--gutter) + 4px);
    color:var(--ink);font-size:15px}
  .bar.js-menu.nav-open .tabs a::before{height:0}
  .bar.js-menu.nav-open .tabs a::after{left:0;right:auto;top:8px;bottom:8px;width:4px;height:auto;border-radius:0 3px 3px 0}
  .bar.js-menu.nav-open .tabs a:hover{background:var(--row-hover)}
  .bar.js-menu.nav-open .tabs a:hover::after{background:transparent}
  .bar.js-menu.nav-open .tabs a.on,.bar.js-menu.nav-open .tabs a[aria-current="page"]{background:var(--accent-soft);color:var(--ink)}
  .bar.js-menu.nav-open .tabs a.on::after,.bar.js-menu.nav-open .tabs a[aria-current="page"]::after{background:var(--accent)}
  .bar.js-menu.nav-open .tabs a:focus-visible{outline-color:var(--focus);outline-offset:-3px}
  /* Without JS the menu wraps onto a second row that scrolls sideways. */
  .bar:not(.js-menu){flex-wrap:wrap;height:auto;row-gap:0;padding-top:8px}
  .bar:not(.js-menu) .tabs{order:10;flex-basis:100%;height:44px;overflow-x:auto;scrollbar-width:none}
}
/* Brand rings watermark behind every authenticated page, one set tucked into
   the top-right corner and one into the bottom-left. Fixed to the viewport so
   they read as a backdrop; z-index 0 keeps them under the content. The ring
   set's CENTRE sits on the corner, so the offsets are half its own size. */
.page-rings{position:fixed;--ring-size:620px;width:var(--ring-size);max-width:none;opacity:.12;
  pointer-events:none;z-index:0;user-select:none}
.page-rings.tr{top:calc(var(--bar-h) - var(--ring-size) / 2);right:calc(var(--ring-size) / -2)}
.page-rings.bl{bottom:calc(var(--ring-size) / -2);left:calc(var(--ring-size) / -2)}
@media (max-width:960px){.page-rings{--ring-size:380px;opacity:.09}}
/* The watermark is position:fixed at z-index 0, so the page content needs its
   own stacking context to sit above it rather than under. */
main{position:relative;z-index:1}

/* ---- page frame ---- */
main{max-width:var(--page-w);margin:0 auto;padding:40px var(--gutter) 76px}
main:focus{outline:none}
@media (max-width:960px){main{padding:24px var(--gutter) 56px}}
/* Positioned and raised so the "?" popover can escape it. The panels below
   are later in the DOM and animate their own opacity, which gives each one a
   stacking context that painted over a popover anchored in a static header.
   Safe against the sticky nav: `main` is itself a stacking context at
   z-index 1, so nothing inside it can rise above `.bar`.
   It wraps: a long `.sub` or a row of actions drops under the title instead
   of squeezing it into a column. */
.head{display:flex;flex-wrap:wrap;align-items:flex-end;gap:10px 14px;margin-bottom:28px;
  position:relative;z-index:60}
.head h1{margin:0;font-size:var(--fs-h1);font-weight:700;letter-spacing:-.025em;line-height:1.15;min-width:0}
.head .sub{color:var(--sec);font-size:14px;font-weight:500;margin-bottom:3px;min-width:0}
.head .btn,.head .linkbtn{margin-left:0}
@media (max-width:720px){
  :root{--fs-h1:24px}
  .head{align-items:flex-start;margin-bottom:20px}
  /* Title first, then everything else on the rows below it. */
  .head h1{flex-basis:100%}
  .head .sp{display:none}
  .head .sub{flex-basis:100%;margin:0}
}
.back{display:inline-flex;align-items:center;gap:6px;min-height:32px;color:var(--sec);font-weight:600;font-size:13.5px;margin-bottom:10px}
.back:hover{color:var(--accent);text-decoration:underline;text-underline-offset:3px}
.section-label{font-size:12.5px;font-weight:700;color:var(--sec);margin:0 0 12px}

/* ---- hero (showcase surfaces only) ---- */
.hero-showcase{position:relative;overflow:hidden;border-radius:var(--r);padding:34px 36px;margin-bottom:32px;
  background:var(--grad-hero);color:#fff}
.hero-showcase h1{margin:0;font-size:var(--fs-h1);font-weight:700;letter-spacing:-.025em;color:#fff}
.hero-showcase .sub{display:block;color:#fff;font-size:15px;font-weight:500;margin-top:6px}
.hero-showcase .rings{position:absolute;right:-58px;top:-86px;width:280px;opacity:.5;pointer-events:none}

/* ---- login (no nav bar here: centered card on the brand wash) ---- */
body.login-page{background:radial-gradient(135% 90% at 50% -10%, #EDE7FA 0%, #F6F3FC 46%, #FBFAFD 100%) top center / 100% 100vh no-repeat #FBFAFD}
body.login-page main{max-width:none;margin:0;padding:0}
.login-view{min-height:100vh;display:flex;flex-direction:column;align-items:center;justify-content:center;padding:40px 16px}
.login-stack{width:100%;max-width:420px;display:flex;flex-direction:column;align-items:center}
.login-mark{width:150px;height:auto;margin-bottom:24px}
.login-card{position:relative;overflow:hidden;width:100%;background:var(--surface);border-radius:var(--r);
  padding:36px 32px 32px;border:1px solid var(--line);
  box-shadow:0 1px 2px rgba(61,47,127,.06),0 8px 24px -12px rgba(61,47,127,.22)}
.login-rings{position:absolute;right:-72px;top:-88px;width:212px;opacity:.14;pointer-events:none}
.login-title{position:relative;margin:0;font-size:24px;font-weight:700;letter-spacing:-.02em;color:var(--ink)}
.login-sub{position:relative;margin:6px 0 24px;font-size:14px;line-height:1.5;color:var(--sec)}
.login-form{position:relative;display:flex;flex-direction:column;gap:18px}
.login-form .field input{width:100%}
.login-btn{display:flex;align-items:center;justify-content:center;gap:10px;width:100%;min-height:48px;text-align:center;border:0;border-radius:var(--r-sm);
  padding:0 16px;cursor:pointer;font-family:inherit;font-size:15px;font-weight:700;color:#fff;
  background:linear-gradient(90deg,#D90A66 0%,#662DFF 100%);transition:filter .15s ease}
.login-btn:hover{filter:brightness(1.08)}
.login-btn[aria-disabled="true"],.login-btn:disabled{cursor:progress;filter:saturate(.7)}
.login-secure{position:relative;display:flex;align-items:flex-start;gap:9px;margin-top:20px;padding-top:18px;
  border-top:1px solid var(--line);font-size:13px;line-height:1.5;color:var(--sec)}
.login-secure svg{flex:none;margin-top:1px;color:var(--accent)}
.login-note{position:relative;margin:18px 0 0;font-size:13px;color:var(--ter);text-align:center}
.login-card .messages{margin:0 0 18px}
@media (max-width:480px){.login-card{padding:28px 20px}.login-mark{width:132px}}

/* ===========================================================
   Component contract (page agents use these; see the brief)
   =========================================================== */

/* ---- utilities ---- */
.sr-only{position:absolute!important;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip:rect(0 0 0 0);white-space:nowrap;border:0}
.nowrap{white-space:nowrap}
.num{text-align:right;font-variant-numeric:tabular-nums;font-feature-settings:"tnum";white-space:nowrap}
:is(th,td).num{text-align:right}

/* ---- native controls, styled once for every page ----
   Wrapped in :where() so the whole block weighs nothing: any page or
   component class still wins without !important. */
:where(main) :where(input:not([type]),input[type=text],input[type=search],input[type=number],
  input[type=date],input[type=month],input[type=time],input[type=datetime-local],input[type=email],
  input[type=password],input[type=url],input[type=tel],select,textarea){
  font:inherit;font-size:14px;letter-spacing:0;color:var(--ink);background-color:var(--surface);
  border:1px solid var(--field-line);border-radius:var(--r-sm);padding:0 12px;min-height:var(--control-h);
  max-width:100%;transition:border-color .15s ease,box-shadow .15s ease}
:where(main) :where(textarea){padding:10px 12px;min-height:96px;line-height:1.5;resize:vertical;width:100%}
:where(main) :where(select){padding-right:34px;cursor:pointer;appearance:none;-webkit-appearance:none;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5l5 5 5-5' fill='none' stroke='%233D2F7F' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right 12px center;background-size:12px 8px}
:where(main) :where(select[multiple]){background-image:none;padding:6px 8px}
:where(main) :where(input,select,textarea)::placeholder{color:var(--placeholder);opacity:1}
:where(main) :where(input,select,textarea):hover:not(:disabled){border-color:var(--sec)}
:where(main) :where(input,select,textarea):focus-visible{outline:2px solid var(--focus);outline-offset:1px;border-color:var(--focus)}
:where(main) :where(input,select,textarea):disabled{background-color:var(--neu-bg);color:var(--neu);cursor:not-allowed;border-color:var(--line)}
:where(main) :where(input,select,textarea)[readonly]{background-color:var(--neu-bg)}
:where(main) :where(input:not([type=checkbox]):not([type=radio]),select,textarea)[aria-invalid="true"]{border-color:var(--bad);box-shadow:inset 0 0 0 1px var(--bad)}
/* A choice group is invalid as a group: the fieldset (or .field) holding it
   gets the red edge, never a box drawn around one radio. */
:where(main) :where(input[type=checkbox],input[type=radio])[aria-invalid="true"]{accent-color:var(--bad);box-shadow:none}
:where(main) :where(fieldset[aria-invalid="true"],fieldset:has(input[aria-invalid="true"])){border-color:var(--bad);box-shadow:inset 0 0 0 1px var(--bad)}
:where(main) :where(input[type=checkbox],input[type=radio]){accent-color:var(--accent);width:18px;height:18px;margin:0;cursor:pointer;vertical-align:middle}
:where(main) :where(input[type=checkbox],input[type=radio]):disabled{cursor:not-allowed}
:where(main) :where(input[type=file]){font:inherit;font-size:13px;max-width:100%}
:where(main) :where(fieldset){border:1px solid var(--line);border-radius:var(--r-sm);padding:14px 16px;margin:0;min-width:0}
:where(main) :where(legend){padding:0 6px;font-weight:700;font-size:13.5px}
/* A label wrapping its checkbox/radio: the whole line is the target. */
.check{display:inline-flex;align-items:center;gap:10px;min-height:32px;cursor:pointer;font-size:14px}
.check input{flex:none}

/* ---- buttons ---- */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;min-height:var(--control-h);
  padding:0 18px;border:1px solid transparent;border-radius:var(--r-sm);background:var(--accent);color:#fff;
  font-family:inherit;font-size:14px;font-weight:600;letter-spacing:-.005em;line-height:1.2;text-align:center;
  white-space:nowrap;cursor:pointer;text-decoration:none;transition:background-color .15s ease,border-color .15s ease,color .15s ease}
.btn:hover{background:var(--accent-strong)}
.btn:active{background:#4A1CC0}
.btn.ghost{background:var(--surface);color:var(--ink);border-color:var(--field-line)}
.btn.ghost:hover{background:var(--accent-soft);border-color:var(--accent);color:var(--accent-strong)}
.btn.danger{background:var(--bad-ink);color:#fff}
.btn.danger:hover{background:#6E1840}
.btn.ghost.danger{background:var(--surface);color:var(--bad-ink);border-color:var(--bad)}
.btn.ghost.danger:hover{background:var(--bad-bg)}
.btn.sm{min-height:var(--control-h-sm);padding:0 12px;font-size:13px}
.btn svg{flex:none}
.btn:disabled,.btn[disabled],.btn[aria-disabled="true"]{background:var(--neu-bg);color:var(--neu);border-color:var(--line);cursor:not-allowed}
.btn.is-busy{cursor:progress}
/* A text button: an action that should not compete with the primary one. */
.linkbtn{display:inline-flex;align-items:center;gap:6px;min-height:32px;padding:4px 6px;margin:0 -6px;
  border:0;background:none;color:var(--accent);font-family:inherit;font-size:14px;font-weight:600;
  cursor:pointer;border-radius:6px;text-decoration:underline;text-decoration-color:transparent;
  text-underline-offset:3px;transition:text-decoration-color .15s ease}
.linkbtn:hover{text-decoration-color:currentColor;color:var(--accent-strong)}
.linkbtn:disabled{color:var(--neu);cursor:not-allowed}
.btn-primary{box-shadow:none}

/* ---- forms ---- */
.field{display:flex;flex-direction:column;gap:6px;min-width:0}
.field>label,.field>.label{font-size:13.5px;font-weight:600;color:var(--ink);line-height:1.35}
.field :where(input:not([type=checkbox]):not([type=radio]),select,textarea){width:100%}
.field .hint{font-size:13px;color:var(--sec);line-height:1.45;margin:0}
.field .err{display:flex;align-items:flex-start;gap:6px;font-size:13px;font-weight:600;color:var(--bad-ink);line-height:1.45;margin:0}
.field .err svg{flex:none;margin-top:1px}
.req{color:var(--bad-ink);font-weight:700;margin-left:2px}
.opt{color:var(--ter);font-weight:500;font-size:12.5px;margin-left:4px}
.form-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:18px 20px}
.form-grid>.full,.form-grid>.span-2{grid-column:1/-1}
@media (max-width:720px){.form-grid{grid-template-columns:minmax(0,1fr)}}
.form-actions{display:flex;flex-wrap:wrap;align-items:center;gap:12px;margin-top:22px}
@media (max-width:480px){.form-actions>.btn{flex:1 1 auto}}

/* ---- callouts ---- */
.notice{display:flex;align-items:flex-start;gap:10px;margin:0 0 16px;padding:12px 16px;
  border:1px solid var(--line);border-radius:var(--r-sm);background:var(--surface);color:var(--ink);
  font-size:14px;line-height:1.5}
.notice>svg{flex:none;margin-top:2px}
.notice>p,.notice .notice-text{margin:0;flex:1;min-width:0}
.notice a:not(.btn){color:var(--accent-strong);font-weight:600;text-decoration:underline;text-underline-offset:3px}
.notice.info{background:var(--accent-soft);border-color:rgba(102,45,255,.28)}
.notice.info>svg{color:var(--accent)}
.notice.warn{background:var(--warn-bg);border-color:rgba(122,91,0,.32)}
.notice.warn>svg{color:var(--warn)}
.notice.bad{background:var(--bad-bg);border-color:rgba(217,10,102,.34);color:var(--bad-ink)}
.notice.bad>svg{color:var(--bad)}
.notice.ok{background:var(--ok-bg);border-color:rgba(11,107,65,.3)}
.notice.ok>svg{color:var(--ok)}
.notice-close{flex:none;display:grid;place-items:center;width:32px;height:32px;margin:-6px -8px -6px 0;
  border:0;border-radius:6px;background:transparent;color:inherit;cursor:pointer}
.notice-close:hover{background:rgba(61,47,127,.08)}
.messages{display:flex;flex-direction:column;gap:8px;margin:0 0 20px}
.messages .notice{margin:0}

/* ---- tables ---- */
/* A wide table scrolls inside its own box, never the page. The shadows at
   either edge appear only while there is more to scroll that way. */
.table-wrap{overflow-x:auto;max-width:100%;-webkit-overflow-scrolling:touch;
  background:
    linear-gradient(to right,var(--surface) 30%,rgba(255,255,255,0)) left center / 40px 100% no-repeat local,
    linear-gradient(to left,var(--surface) 30%,rgba(255,255,255,0)) right center / 40px 100% no-repeat local,
    radial-gradient(farthest-side at 0 50%,rgba(61,47,127,.16),rgba(61,47,127,0)) left center / 12px 100% no-repeat scroll,
    radial-gradient(farthest-side at 100% 50%,rgba(61,47,127,.16),rgba(61,47,127,0)) right center / 12px 100% no-repeat scroll}
.table-wrap:focus-visible{outline:2px solid var(--focus);outline-offset:-2px}
.table-wrap>table{min-width:var(--table-min,640px)}
table{width:100%;border-collapse:collapse}
thead th{text-align:left;padding:12px 20px;font-size:12.5px;font-weight:600;color:var(--sec);border-bottom:1px solid var(--line);vertical-align:bottom}
tbody td{padding:14px 20px;border-bottom:1px solid var(--line-2);vertical-align:middle}
tbody tr:last-child td{border-bottom:0}
@media (max-width:720px){
  thead th{padding:10px 14px}
  tbody td{padding:12px 14px}
}
/* Row navigation (app.js): the whole row opens its page, and a real link
   inside it carries keyboard and screen-reader users there. */
tr[data-href]{cursor:pointer}
tr[data-href]:hover>td,tr[data-href]:focus-within>td{background:var(--row-hover)}
tr[data-href] a{color:inherit}
tr[data-href] a:hover{text-decoration:underline;text-underline-offset:3px}
tbody tr.clickable{cursor:pointer;transition:background .15s ease}
tbody tr.clickable:hover{background:var(--row-hover)}

/* ---- error pages (404 / 403) ---- */
.errpage{max-width:640px;padding:24px 0 8px}
.errpage h1{margin:0 0 12px}
.errpage-lead{margin:0 0 10px;font-size:16px;color:var(--ink)}
.errpage-hint{margin:0;color:var(--sec);max-width:60ch}
.errpage-path{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:14px;background:var(--neu-bg);
  padding:1px 6px;border-radius:4px;overflow-wrap:anywhere}

/* ---- toolbar, search, filters (legacy names kept) ---- */
.toolbar{display:flex;flex-wrap:wrap;align-items:center;gap:10px;margin-bottom:18px}
.search{position:relative;width:300px;max-width:100%}
.search input,input.search{width:100%;padding:0 13px 0 38px}
input.search{width:300px;max-width:100%;padding:0 13px}
.search svg{position:absolute;left:12px;top:50%;transform:translateY(-50%);color:var(--sec);pointer-events:none}
.filterbtn{display:inline-flex;align-items:center;gap:7px;min-height:var(--control-h);background-color:var(--surface);
  border:1px solid var(--field-line);border-radius:var(--r-sm);padding:0 14px;font-family:inherit;font-weight:500;color:var(--ink);font-size:14px;cursor:pointer}
select.filterbtn{padding-right:34px}
.filterbtn:hover{border-color:var(--accent);color:var(--accent-strong)}
@media (max-width:720px){
  .toolbar>*{flex:1 1 100%}
  .toolbar>.btn{flex:0 0 auto}
  .search,input.search{width:100%}
}
.chip{display:inline-flex;align-items:center;gap:7px;background:var(--accent-soft);color:var(--accent-strong);padding:5px 12px;border-radius:999px;font-size:13px;font-weight:600}
.chip .x{font-weight:700;cursor:pointer}

/* ---- in-page tab bar ----
   Scrolls sideways when it does not fit; the active item carries
   aria-current="page" (or the legacy .on). */
.seg{display:flex;max-width:100%;overflow-x:auto;scrollbar-width:none;background:#EDEBF3;border-radius:10px;padding:3px;gap:2px;position:relative;width:max-content}
.seg::-webkit-scrollbar{display:none}
.seg a,.seg button{display:inline-flex;align-items:center;min-height:36px;padding:0 14px;font-family:inherit;font-weight:500;font-size:13.5px;color:var(--sec);
  background:none;border:0;border-radius:8px;white-space:nowrap;position:relative;z-index:1;cursor:pointer;transition:color .15s ease,background-color .15s ease}
.seg a:hover,.seg button:hover{color:var(--ink)}
.seg a.on,.seg a[aria-current="page"],.seg button[aria-pressed="true"]{color:var(--ink);font-weight:700}
/* No sliding indicator: the active item paints its own white tile. */
.seg:not(:has(.seg-ind)) :is(a.on,a[aria-current="page"],button[aria-pressed="true"]){background:var(--surface);
  box-shadow:0 1px 2px rgba(61,47,127,.14),0 0 0 1px rgba(61,47,127,.06)}
.seg :focus-visible{outline-offset:-2px}
.seg-ind{position:absolute;top:3px;height:calc(100% - 6px);left:0;width:0;background:#fff;border-radius:8px;z-index:0;
  box-shadow:0 1px 2px rgba(61,47,127,.14),0 0 0 1px rgba(61,47,127,.06);
  transition:transform .2s ease,width .2s ease}
@media (max-width:720px){.seg{width:auto}}

/* ---- pagination ---- */
.pag{display:flex;flex-wrap:wrap;align-items:center;gap:8px 16px;padding:14px 20px;color:var(--sec);font-size:13.5px;border-top:1px solid var(--line-2)}
.pag .pag-info{font-variant-numeric:tabular-nums}
.pag .pag-links{display:flex;gap:8px;margin-left:auto}
.pag a{display:inline-flex;align-items:center;gap:4px;min-height:36px;padding:0 12px;border:1px solid var(--field-line);border-radius:var(--r-sm);color:var(--accent-strong);font-weight:600;background:var(--surface)}
.pag a:hover{background:var(--accent-soft);border-color:var(--accent)}
.pag .pag-off{display:inline-flex;align-items:center;gap:4px;min-height:36px;padding:0 12px;border:1px solid var(--line);border-radius:var(--r-sm);color:var(--ter);font-weight:600}
@media (max-width:480px){.pag .pag-links{margin-left:0;width:100%}.pag .pag-links>*{flex:1;justify-content:center}}

/* The date pair as a single chip, bordered and sized like `.filterbtn`
   beside it, so a range reads as one filter rather than two loose fields.
   The native inputs keep their own dd/mm/aaaa affordance, so no label is
   needed; `min-width:0` lets them shrink with the chip instead of forcing
   the toolbar wider than the panel. */
.daterange{display:inline-flex;align-items:center;gap:4px;background:var(--surface);
  border:1px solid var(--line);border-radius:11px;padding:8px 11px;
  transition:border-color .18s ease}
.daterange:focus-within{border-color:var(--accent);outline:2px solid var(--focus);outline-offset:1px}
.daterange input{min-width:0;width:122px;border:0;background:transparent;padding:0;
  font-family:inherit;font-size:13.5px;color:var(--ink)}
.daterange input:focus-visible{outline:none}
/* An empty date input renders its placeholder in the same ink as a filled
   one, so an unset range would read as a set one. */
.daterange input:not(:valid){color:var(--icon-muted)}
.daterange-sep{color:var(--icon-muted);font-size:13px}

.crm-reference-form{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin:0 14px 4px 0}
.head-title{display:flex;flex-direction:column;gap:5px}
.head-title .sub{margin-bottom:0}

/* KPI custom range: the date form that "Personalizado" opens. It is inserted
   into a head that was already on screen, so it slides out of the pill strip
   instead of blinking into existence. The fields arrive just behind the row
   itself, which is what makes it read as one control opening rather than
   three elements landing together. */
@keyframes rangeIn{from{opacity:0;transform:translateX(14px)}
  to{opacity:1;transform:none}}
.range-row{display:flex;align-items:center;gap:10px;flex-wrap:wrap;
  margin:0 14px 4px 0;
  animation:rangeIn .34s cubic-bezier(.22,1,.36,1) both}
.crm-reference-form,.range-row>*,.crm-reference-form>*{animation:rangeIn .34s cubic-bezier(.22,1,.36,1) both}
.range-row>*:nth-child(1),.crm-reference-form>*:nth-child(1){animation-delay:.04s}
.range-row>*:nth-child(2),.crm-reference-form>*:nth-child(2){animation-delay:.08s}
.range-row>*:nth-child(3),.crm-reference-form>*:nth-child(3){animation-delay:.12s}
/* Leaving is the same motion run backwards, and faster: an exit the eye has
   to wait for is an exit that feels stuck. app.js adds the class and holds
   the swap back for exactly this long before replacing the markup. */
@keyframes rangeOut{from{opacity:1;transform:none}
  to{opacity:0;transform:translateX(14px)}}
.range-row.range-leaving,.crm-reference-form.range-leaving{animation:rangeOut .18s ease-in both}
.range-row.range-leaving>*,.crm-reference-form.range-leaving>*{animation:none}
form.range-stable:not(.range-leaving),form.range-stable:not(.range-leaving)>*{animation:none}
@media(prefers-reduced-motion:reduce){
  .range-row,.range-row>*,.range-row.range-leaving,.crm-reference-form,.crm-reference-form>*,.crm-reference-form.range-leaving{animation:none}
}

/* switcher fetch-swap: dims the swapped region while its request is in flight */
.swap-loading{opacity:.55;pointer-events:none;transition:opacity .15s ease}
/* Tabs keep their own header and geometry while only the body is loading. */
[data-swap-content]{position:relative}
.tab-waiting > :not(.head):not([data-tab-loading]){visibility:hidden;pointer-events:none}
[data-tab-loading]{position:absolute;left:0;right:0;bottom:0;overflow:hidden;pointer-events:none;animation:tabLoadingIn .14s ease-out both}

/* Legacy name for a warning strip; new markup uses .notice.warn. */
.tab-error{display:flex;flex-wrap:wrap;align-items:center;gap:10px 16px;padding:12px 16px;margin-bottom:18px;background:var(--warn-bg);border:1px solid rgba(122,91,0,.32);border-radius:var(--r-sm);font-size:14px;color:var(--ink)}
.tab-error a{color:var(--accent-strong);font-weight:600;text-decoration:underline;text-underline-offset:3px}
@keyframes tabLoadingIn{from{opacity:.35}to{opacity:1}}
@keyframes tabContentIn{from{opacity:.4;transform:translateY(3px)}to{opacity:1;transform:none}}
/* One body transition, not an ancestor fade multiplied by a 550ms panel fade. */
[data-swap-content].swap-tab :is(.panel,.summary,.toolbar,.banner,.reveal,.alert,.tile,.kpi,tbody tr.clickable){animation:none!important;opacity:1}
[data-swap-content].swap-tab > :not(.head):not([data-tab-loading]){animation:tabContentIn .32s cubic-bezier(.22,1,.36,1) both!important}
/* The status distribution is already sized by the response. Its page-load
   reveal hides it for 500ms after the surrounding tab has arrived. Let the
   body transition carry the complete bar, with no second entrance. */
[data-swap-content].swap-tab .distbar{animation:none;clip-path:none}
@media(prefers-reduced-motion:reduce){
  [data-tab-loading],[data-swap-content].swap-tab > :not(.head):not([data-tab-loading]){animation:none!important}
  [data-tab-loading] .skel::after{animation:none}
}
/* A swapped region is not a page load, but it is still new content, so it
   should arrive rather than appear. Durations are left exactly as designed —
   overriding them is what made a switch feel snappy instead of smooth. What
   goes is the wait before the containers arrive: on load, a panel is blank
   for 240ms before it fades, which is fine after a navigation and reads as
   a flicker after a 40ms fetch. The containers now start immediately and
   fade over their own unchanged .55s, and everything inside them — bars,
   lines, donuts, sparklines — keeps its own timing untouched, so the motion
   within a card is identical to a fresh load. */
[data-swap-content].swapped :is(.summary,.toolbar,.panel,.banner,.reveal,
  .alert,.tile,.kpi,tbody tr.clickable){animation-delay:0s!important}
/* The head is the exception: the title and the tab bar are the same before
   and after, so animating them announces a reload that did not happen. */
[data-swap-content].swapped .head{opacity:1!important;animation:none!important}
/* Moving between SCREENS through the menu. The per-element entrance is the
   page-LOAD animation: panels fading up from nothing on a stagger, `.head`
   at .02s, `.summary` at .10s, `.toolbar` at .18s, `.panel` at .24s. Playing
   that over a screen that is already in place is what reads as the page
   loading a second time, so the elements arrive already visible...  */
[data-swap-content].swap-screen :is(.head,.summary,.toolbar,.panel,
  .banner,.reveal,.alert,.tile,.kpi,.quotes-tab-content){
  opacity:1!important;animation:none!important}
/* ...and the REGION carries the motion instead, as one piece. Suppressing
   the stagger without this left the swap a hard cut with no motion at all.
   It starts at .35 rather than 0 on purpose: from 0 the screen goes blank
   first, which is the very flash both halves of this exist to remove. Short
   enough (.18s) that it never delays reading, and it cannot be mistaken for
   a second load because nothing ever disappears. */
[data-swap-content].swap-in{animation:swapScreenIn .18s ease-out both}
@keyframes swapScreenIn{from{opacity:.35;transform:translateY(4px)}
  to{opacity:1;transform:none}}
@media(prefers-reduced-motion:reduce){
  [data-swap-content].swap-in{animation:none}}

/* ---- summary / distribution bar ---- */
.summary{margin-bottom:22px}
.summary .n{font-size:44px;font-weight:700;letter-spacing:-.035em;line-height:1}
.summary .cap{color:var(--ter);font-size:14px;font-weight:500;margin:9px 0 0}
.distbar{display:flex;height:10px;border-radius:999px;overflow:hidden;background:var(--neu-bg);width:100%;box-shadow:inset 0 0 0 1px rgba(20,20,30,.04)}
.distbar span{display:block;height:100%;transition:filter .2s ease}
.distbar:hover span{filter:saturate(1.15)}
.legend{display:flex;gap:28px;margin-top:18px;flex-wrap:wrap}
.legend .it{display:flex;align-items:center;gap:9px;font-size:13.5px;color:var(--sec);font-weight:500}
.legend .it .dot{width:8px;height:8px;border-radius:50%}
.legend .it b{color:var(--ink);font-weight:600}

/* ---- panel / table ---- */
.panel{background:var(--surface);border-radius:var(--r);box-shadow:var(--shadow);overflow:hidden;border:1px solid var(--line-2)}
.panel.pad{padding:22px 24px}
/* Safety net on phones: a table nobody wrapped in .table-wrap scrolls inside
   its card instead of being cut off by the card's clipping. */
@media (max-width:720px){.panel{overflow-x:auto}.panel.pad{padding:18px 16px}}
.fname{font-weight:600;font-size:14.5px;letter-spacing:-.01em}
.sub-cnpj{color:var(--ter);font-size:12.5px;margin-top:3px;font-weight:500;letter-spacing:0}
.type,.when{color:var(--sec);font-size:13.5px}
.motivo{color:var(--ter);font-size:12px;margin-top:6px;font-weight:500;max-width:240px}
.valor{font-weight:600;color:var(--ink);font-variant-numeric:tabular-nums}
.flag{display:inline-flex;vertical-align:-1px;margin-right:7px;color:var(--bad)}
tbody tr.risk td:first-child{box-shadow:inset 3px 0 0 var(--bad)}
.chev{color:var(--icon-muted);font-size:19px;text-align:right;width:26px;transition:color .18s ease,transform .18s ease}
tbody tr.clickable:hover .chev{color:var(--accent)}

.rc{display:inline-flex;align-items:center;gap:7px;padding:6px 11px;
  border:1px solid var(--line);border-radius:999px;background:var(--surface);
  color:var(--sec);font-size:12.5px;font-weight:600;text-transform:capitalize;
  transition:border-color .18s ease,color .18s ease,background .18s ease}
.rc:hover{border-color:var(--accent);color:var(--accent)}
.rc.on{background:var(--accent-soft);border-color:var(--accent-soft-2);
  color:var(--accent)}

.products-chevron{display:inline-block;color:var(--icon-muted);font-size:15px;line-height:1;transition:transform .18s ease}
.products-chevron.is-expanded{transform:rotate(180deg)}

/* ---- status pill ---- */
.st{display:inline-flex;align-items:center;gap:7px;padding:4px 11px;border-radius:999px;font-size:12.5px;font-weight:600;letter-spacing:-.01em;white-space:nowrap;line-height:1.4}
.st .dot{width:6px;height:6px;border-radius:50%}
.st.ok{background:var(--ok-bg);color:var(--ok)} .st.ok .dot{background:var(--ok-ico)}
.st.warn{background:var(--warn-bg);color:var(--warn)} .st.warn .dot{background:var(--warn-ico)}
.st.bad{background:var(--bad-bg);color:var(--bad)} .st.bad .dot{background:var(--bad-ico)}
.st.neu{background:var(--neu-bg);color:var(--neu)} .st.neu .dot{background:var(--neu-ico)}
.st.ressalva{background:var(--ressalva-bg);color:var(--ressalva)} .st.ressalva .dot{background:var(--ressalva-ico)}
.st.bloqueio{background:var(--bloqueio-bg);color:var(--bloqueio)} .st.bloqueio .dot{background:var(--bloqueio-ico)}
/* In progress: the run is still going. The dot breathes (opacity only); the
   reduced-motion rule below stops it, and the label says it in words. */
.st.run{background:var(--accent-soft);color:var(--accent-strong)} .st.run .dot{background:var(--accent);animation:stPulse 1.4s ease-in-out infinite}
@keyframes stPulse{0%,100%{opacity:1}50%{opacity:.3}}

/* ---- KPI band (single panel, internal dividers) ---- */
.kpis{display:flex}
.kpi{flex:1;padding:21px 24px;border-left:1px solid var(--line-2);display:flex;flex-direction:column}
.kpi:first-child{border-left:0}
.kpi .l{color:var(--sec);font-size:13px;font-weight:500}
.kpi .top{display:flex;align-items:flex-end;justify-content:space-between;gap:10px;margin-top:9px}
.kpi .v{font-size:29px;font-weight:700;letter-spacing:-.03em;line-height:.95}
.kpi .d{display:inline-flex;align-items:center;gap:4px;font-size:12.5px;font-weight:600;margin-top:9px}
.kpi .d.up{color:var(--ok)} .kpi .d.down{color:var(--bad)} .kpi .d.flat{color:var(--ter)}
.kpi .sub{color:var(--ter);font-size:12px;font-weight:500;margin-top:7px;line-height:1.35}



/* ---- bar chart (execuções por dia) ---- */
.chart{display:flex;align-items:flex-end;gap:6px;height:200px;padding-top:8px}
.chart .col{flex:1;display:flex;flex-direction:column-reverse;height:100%;justify-content:flex-start;gap:2px;
  transform:scaleY(0);transform-origin:bottom;animation:growY .8s cubic-bezier(.22,1,.36,1) forwards}
.chart .col .seg-bar{width:100%;border-radius:3px}
.chart .col .seg-bar.approved{background:var(--ok-ico)}
.chart .col .seg-bar.pending{background:var(--warn-ico)}
.chart .col .seg-bar.rejected{background:var(--bad-ico)}
.chart .col .seg-bar.other{background:var(--neu-ico)}
.legend .it .dot.approved{background:var(--ok-ico)}
.legend .it .dot.pending{background:var(--warn-ico)}
.legend .it .dot.rejected{background:var(--bad-ico)}
.legend .it .dot.other{background:var(--neu-ico)}
.chart-x{display:flex;gap:6px;margin-top:10px}
/* min-width:0 is load-bearing: a flex item defaults to min-width:auto, so a
   span holding a date would refuse to shrink below its text while the empty
   spans collapsed, and the strip stopped lining up with the columns above it.
   The dates now sit on the same track as the bars and overflow the empty
   neighbours, which is why they must not wrap. */
.chart-x span{flex:1;min-width:0;text-align:center;font-size:12px;color:var(--ter);font-weight:500;white-space:nowrap;overflow:visible}

/* ---- alerts ---- */
.alert{display:flex;gap:14px;padding:18px 22px;border-bottom:1px solid var(--line-2);align-items:flex-start;transition:background .15s ease}
.alert:last-child{border-bottom:0}
.alert:hover{background:#FAFAFC}
.alert.unread{box-shadow:inset 3px 0 0 var(--accent)}
.alert .ic{width:22px;display:grid;place-items:center;flex:none;margin-top:1px}
.alert .ic svg{width:20px;height:20px}

.alert .ic.warn{color:var(--warn)}
.alert .ic.info{color:var(--accent)}
.alert .body{flex:1;min-width:0}
.alert .t{font-weight:600;font-size:14.5px;letter-spacing:-.01em}
.alert.unread .t::after{content:"";display:inline-block;width:7px;height:7px;border-radius:50%;background:var(--accent);margin-left:8px;vertical-align:middle}
.alert .m{color:var(--sec);font-size:13px;margin-top:4px}
.alert .meta{color:var(--ter);font-size:12.5px;margin-top:7px;font-weight:500}
.alert .when{color:var(--ter);font-size:12.5px;font-weight:500;white-space:nowrap;margin-left:8px}

/* EXPERIMENT (revert this commit to restore): the grey title bar is gone from
   every card head across the dashboard, leaving the rule alone to separate the
   title from the body. Kept in one commit so the whole look flips back at once. */
.panel-head{display:flex;align-items:center;gap:10px;padding:16px 22px;
  border-bottom:1px solid var(--line-2)}
/* Body of a panel that has a head bar. `.panel.pad` cannot serve: it pads the
   card itself, which would inset the bar too. */
.panel-body{padding:22px 24px;flex:1}
.panel-head .ttl{font-size:14px;font-weight:700;letter-spacing:-.01em}
.panel-head .cnt{background:var(--bad-bg);color:var(--bad);font-size:12px;font-weight:700;padding:1px 9px;border-radius:999px}
.panel-head a:not(.btn){display:inline-flex;align-items:center;min-height:24px;margin-left:auto;color:var(--accent-strong);font-weight:600;font-size:13px}
.panel-head a:not(.btn):hover{text-decoration:underline;text-underline-offset:3px}
/* Muted qualifier beside a panel title, for what the panel's own figure
   cannot say: a ring drawn from a partial sweep is green either way. */
.panel-head .qual{margin-left:auto;color:var(--sec);font-size:12.5px;font-weight:500}
/* A search form living in a panel head. Placement comes from a `.sp` spacer
   in the markup, not from an auto margin here: `.panel-head a` already sets
   margin-left:auto for trailing links, and the Limpar link sits INSIDE this
   form, so an auto margin on the form competes with a rule doing the same job
   one level down. Only the standalone toolbar's bottom margin is cancelled,
   which would otherwise shove the head's border away from its text. */
.panel-head .toolbar{margin-bottom:0}
/* Undo `.panel-head a{margin-left:auto;color:var(--accent);font-weight:500;
   font-size:13px}` for the buttons inside that form: that rule exists to push
   a lone trailing link to the far right of a head and to read as a quiet text
   link there, and applied to the "Limpar" `<a class="btn ghost">` it both
   tears Limpar away from Buscar AND repaints it in accent purple at the wrong
   weight and size instead of `.btn.ghost`'s `--ink`/600/14px, so it stops
   matching the "Buscar" button beside it. */
.panel-head .toolbar a{margin-left:0;color:var(--ink);font-weight:600;font-size:14px}
.panel-head .search{width:260px}
.panel-head .search input{padding-left:13px}
.type-legend .row.tot{color:var(--sec);font-weight:600;margin-bottom:6px;cursor:default}
.type-legend .row.tot:hover{background:transparent}

/* line / area chart */
.linechart svg{display:block;width:100%;height:auto;overflow:visible}
.linechart .area{transform-origin:bottom;transform:scaleY(0);animation:growY 1s cubic-bezier(.22,1,.36,1) .35s forwards}
.linechart .line{fill:none;stroke:var(--accent);stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round;
  stroke-dasharray:1;stroke-dashoffset:1;animation:draw 1.5s cubic-bezier(.22,1,.36,1) .3s forwards}
.linechart .dot{fill:var(--accent);opacity:0;animation:fadeUp .4s ease forwards;animation-delay:1.4s}

@keyframes draw{to{stroke-dashoffset:0}}

.tile{background:var(--surface);border-radius:var(--r);box-shadow:var(--shadow);padding:22px 24px;overflow:hidden;display:flex;flex-direction:column;min-width:0;position:relative;
  opacity:0;animation:fadeUp .55s cubic-bezier(.22,1,.36,1) forwards}
.tile.flush{padding:0}
.tile .section-label{margin:0 0 14px}

.tile .d{display:inline-flex;align-items:center;gap:4px;font-size:12.5px;font-weight:600;margin-top:8px}
.tile .d.up{color:var(--ok)}.tile .d.down{color:var(--bad)}
.tile:nth-child(1){animation-delay:.04s}.tile:nth-child(2){animation-delay:.09s}
.tile:nth-child(3){animation-delay:.14s}.tile:nth-child(4){animation-delay:.19s}
.tile:nth-child(5){animation-delay:.24s}.tile:nth-child(6){animation-delay:.29s}
.tile:nth-child(7){animation-delay:.34s}.tile:nth-child(8){animation-delay:.39s}
.tile:nth-child(9){animation-delay:.44s}.tile:nth-child(10){animation-delay:.49s}
.tile.scroll{overflow-y:auto}
@media(max-width:980px){.tile{grid-column:auto!important;grid-row:auto!important;min-height:150px}}

/* ---- open stat band (not boxed) ---- */
.stats-open{display:flex;border-top:1px solid var(--line);border-bottom:1px solid var(--line);margin-bottom:30px}
.stats-open .st-item{flex:1;padding:18px 26px;border-left:1px solid var(--line-2)}
.stats-open .st-item:first-child{border-left:0;padding-left:2px}
.stats-open .l{color:var(--sec);font-size:12.5px;font-weight:500}
.stats-open .v{font-size:27px;font-weight:700;letter-spacing:-.025em;margin-top:7px;line-height:1}
.stats-open .d{display:inline-flex;gap:4px;font-size:12.5px;font-weight:600;margin-top:8px}
.stats-open .d.up{color:var(--ok)}.stats-open .d.down{color:var(--bad)}.stats-open .d.flat{color:var(--ter)}
.stats-open .sub{color:var(--ter);font-size:12px;font-weight:500;margin-top:7px;line-height:1.35}

/* ---- skeleton loading ---- */
.skel{position:relative;overflow:hidden;background:#E9E9EE;border-radius:8px}
.skel::after{content:"";position:absolute;inset:0;transform:translateX(-100%);
  background:linear-gradient(90deg,transparent,rgba(255,255,255,.65),transparent);animation:shimmer 1.3s infinite}
.sk-line{height:14px;border-radius:6px}
.sk-title{width:240px;max-width:70%;height:26px;margin:4px 0 26px}
.sk-block{margin-bottom:16px}
.sk-h52{height:52px}.sk-h150{height:150px}.sk-h180{height:180px}.sk-h260{height:260px}.sk-h360{height:360px}
.sk-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:16px}
.sk-grid>.sk-block{margin-bottom:0}
@media (max-width:720px){.sk-grid{grid-template-columns:minmax(0,1fr)}}
@keyframes shimmer{100%{transform:translateX(100%)}}

/* ---- hero donut (pizza) ---- */
.hero-flex{display:flex;align-items:center;justify-content:space-between;gap:48px;flex-wrap:wrap}

.donut{width:138px;height:138px;flex:none;transform-origin:center;animation:popIn .6s cubic-bezier(.34,1.4,.5,1) .25s both}
@keyframes popIn{from{opacity:0;transform:scale(.85)}to{opacity:1;transform:none}}

/* nested mini-cards inside a panel */
/* minmax(0,1fr) rather than 1fr: .mini .v is white-space:nowrap, so a long
   value like "R$ 42.269,30" sets a min-content floor that a plain 1fr track
   cannot go below. That widened the currency column, and aspect-ratio:1 then
   made that card taller than its neighbours. */
.mini-cards{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:12px;margin-top:20px;align-items:start}

.donut-c{position:relative;width:152px;height:152px;animation:popIn .6s cubic-bezier(.34,1.4,.5,1) .3s both}
.donut-c svg{width:152px;height:152px;transform:rotate(-90deg);display:block}
.donut-c circle{fill:none;stroke-width:15}
.donut-c .ctr{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center}
.donut-c .ctr .n{font-size:32px;font-weight:700;letter-spacing:-.03em;line-height:1}
.donut-c .ctr .t{color:var(--ter);font-size:12px;font-weight:600;margin-top:3px;text-transform:uppercase;letter-spacing:.04em}
.type-legend{display:flex;flex-direction:column;margin-top:20px;width:100%}
.type-legend .row{display:flex;align-items:center;gap:11px;padding:9px 0;border-bottom:1px solid var(--line-2);font-size:13.5px;
  opacity:0;animation:fadeUp .5s cubic-bezier(.22,1,.36,1) forwards}
.type-legend .row:last-child{border-bottom:0}
.type-legend .row:nth-child(1){animation-delay:.45s}.type-legend .row:nth-child(2){animation-delay:.51s}
.type-legend .row:nth-child(3){animation-delay:.57s}.type-legend .row:nth-child(4){animation-delay:.63s}
.type-legend .row:nth-child(5){animation-delay:.69s}.type-legend .row:nth-child(6){animation-delay:.75s}
.type-legend .dot{width:10px;height:10px;border-radius:50%;flex:none}
.type-legend .row.z{cursor:default}
.type-legend .row.z .nm,.type-legend .row.z .ct,.type-legend .row.z .dot{opacity:.5}
.type-legend .row.z:hover{background:transparent}
.type-legend .nm{flex:1;font-weight:500}
.type-legend .ct{font-weight:700;font-variant-numeric:tabular-nums}
.type-legend .pc{color:var(--ter);font-size:12px;width:40px;text-align:right;font-variant-numeric:tabular-nums}
.grid-2>.panel{display:flex;flex-direction:column}

.banner{border-radius:var(--r);box-shadow:var(--shadow);background:var(--surface);padding:22px 24px;margin-bottom:26px;position:relative;overflow:hidden}
.banner::before{content:"";position:absolute;left:0;top:0;bottom:0;width:4px}
.banner.bad::before{background:var(--bad)} .banner.ok::before{background:var(--ok)} .banner.warn::before{background:var(--warn)}
.banner .verdict{display:flex;align-items:center;gap:12px}
.banner .verdict h2{margin:0;font-size:18px;font-weight:700;letter-spacing:-.02em}
.banner .just{color:var(--sec);font-size:14px;margin-top:10px}
.banner ul{margin:12px 0 0;padding:0;list-style:none}
.banner li{display:flex;align-items:flex-start;gap:9px;padding:6px 0;color:var(--ink);font-size:13.5px}
.banner li::before{content:"›";color:var(--bad);font-weight:700;margin-top:-1px}
.grid-2{display:grid;grid-template-columns:1.5fr 1fr;gap:22px;align-items:stretch}
.grid-2>.panel{display:flex;flex-direction:column}
.grid-2-even{display:grid;grid-template-columns:1fr 1fr;gap:22px;align-items:stretch}
.grid-2-even>.panel{display:flex;flex-direction:column}
@media (max-width:960px){.grid-2,.grid-2-even{grid-template-columns:minmax(0,1fr)}}
.block{margin-bottom:24px}
.kv{display:grid;grid-template-columns:auto 1fr;gap:11px 18px}
.kv dt{color:var(--sec);font-size:13px;font-weight:500}
.kv dd{margin:0;font-weight:600;font-size:13.5px;text-align:right}
.rules td{padding:13px 22px;font-size:13.5px}
.rules .rn{font-weight:600}
.rules .rmsg{color:var(--ter);font-size:12px;margin-top:3px}
.stage{display:flex;align-items:center;gap:12px;padding:11px 0;border-bottom:1px solid var(--line-2);font-size:13.5px}
.stage:last-child{border-bottom:0}
.stage .ck{width:20px;height:20px;border-radius:50%;display:grid;place-items:center;flex:none;font-size:12px;font-weight:700}
.stage .ck.ok{background:var(--ok-bg);color:var(--ok)}
.stage .ck.bad{background:var(--bad-bg);color:var(--bad)}
.stage .nm{flex:1}.stage .dur{color:var(--ter);font-size:12.5px;font-variant-numeric:tabular-nums}

/* ---- stacked time-composition bar ---- */
.timebar{display:flex;height:32px;border-radius:11px;overflow:hidden;background:#F1F1F5;margin-top:6px;
  box-shadow:inset 0 0 0 1px rgba(20,20,30,.04);clip-path:inset(0 100% 0 0);animation:barReveal 1s cubic-bezier(.22,1,.36,1) .35s forwards}
.timebar span{display:block;height:100%;cursor:pointer;transition:filter .18s ease}
.timebar:hover span{filter:saturate(.7) brightness(1.05)}
.timebar span:hover{filter:saturate(1.18) brightness(1.06)!important}

.summary .topline{display:flex;align-items:center;gap:14px}

.st.placeholder{background:var(--neu-bg);color:var(--neu)} .st.placeholder .dot{background:var(--neu)}

/* ===== interactive: tooltip + hover states ===== */
.tip{position:fixed;z-index:60;pointer-events:none;left:0;top:0;
  background:#16161A;color:#fff;border-radius:11px;padding:10px 13px;font-size:12.5px;font-weight:500;
  box-shadow:0 10px 30px rgba(20,20,30,.22),0 2px 6px rgba(20,20,30,.14);
  opacity:0;transform:translateY(5px) scale(.97);transform-origin:bottom left;
  transition:opacity .14s ease,transform .18s cubic-bezier(.34,1.4,.5,1);white-space:nowrap}
.tip.on{opacity:1;transform:none}
.tip .tt{font-weight:700;font-size:12.5px;margin-bottom:6px;letter-spacing:-.01em}
.tip .rr{display:flex;align-items:center;gap:16px;justify-content:space-between;margin-top:4px;font-size:12px;color:rgba(255,255,255,.78)}
.tip .rr .nm{display:flex;align-items:center;gap:7px}
.tip .rr .dot{width:7px;height:7px;border-radius:50%;flex:none}
.tip .rr b{color:#fff;font-weight:700;font-variant-numeric:tabular-nums}
.tip .big{font-size:18px;font-weight:700;letter-spacing:-.02em}

/* daily chart hover */
.chart .col{transition:opacity .2s ease,filter .2s ease;cursor:pointer}
.chart.dim .col:not(.hot){opacity:.3;filter:saturate(.55)}
.chart.dim .col.hot{filter:saturate(1.12)}

/* donut hover */
.donut-c circle{transition:opacity .22s ease,stroke-width .22s cubic-bezier(.34,1.4,.5,1)}
.donut-c.dim circle:not(.hot){opacity:.26}
.donut-c circle.hot{stroke-width:19}
.type-legend .row{cursor:pointer;border-radius:8px;transition:background .15s ease}
.type-legend .row:hover{background:#FAFAFC}

/* line chart hover */
.linechart{position:relative}
.lc-pts circle{cursor:pointer}
.lc-hot{fill:#fff;stroke:var(--accent);stroke-width:3;opacity:0;transition:opacity .15s ease}
.lc-hot.on{opacity:1}
.lc-guide{stroke:var(--line);stroke-width:1;stroke-dasharray:3 3;opacity:0;transition:opacity .15s ease}
.lc-guide.on{opacity:1}

/* ===== motion ===== */
/* Entrances are short and nearly static: the analyst opens these screens
   dozens of times a day, and a page that takes most of a second to settle
   reads as slow, not as polished. */
@keyframes fadeUp{from{opacity:0;transform:translateY(4px)}to{opacity:1;transform:none}}
@keyframes barReveal{from{clip-path:inset(0 100% 0 0)}to{clip-path:inset(0 0 0 0)}}
@keyframes growY{to{transform:scaleY(1)}}
@keyframes growX{to{width:var(--w,100%)}}
@keyframes growXIn{from{width:0}to{width:var(--w,100%)}}
.head{opacity:0;animation:fadeUp .22s ease-out forwards}
.summary{opacity:0;animation:fadeUp .22s ease-out .03s forwards}
.toolbar{opacity:0;animation:fadeUp .22s ease-out .04s forwards}
.reveal{opacity:0;animation:fadeUp .22s ease-out forwards}
.panel:not(.no-anim){opacity:0;animation:fadeUp .25s ease-out .06s forwards}
.banner{opacity:0;animation:fadeUp .22s ease-out .04s forwards}
.distbar{clip-path:inset(0 100% 0 0);animation:barReveal 1.05s cubic-bezier(.22,1,.36,1) .5s forwards}
.d-1{animation-delay:.10s!important}.d-2{animation-delay:.18s!important}.d-3{animation-delay:.26s!important}
.d-4{animation-delay:.34s!important}.d-5{animation-delay:.42s!important}
/* staggered children */
.kpi:nth-child(1){animation-delay:.05s}.kpi:nth-child(2){animation-delay:.12s}
.kpi:nth-child(3){animation-delay:.19s}.kpi:nth-child(4){animation-delay:.26s}.kpi:nth-child(5){animation-delay:.33s}
.chart .col:nth-child(n){animation-delay:calc(.4s + (var(--i,0) * .03s))}

@media (prefers-reduced-motion:reduce){
  *{animation:none!important;transition:none!important}
  .head,.summary,.toolbar,.panel,.banner,tbody tr,.alert,.reveal,.tile{opacity:1!important}
  .distbar{clip-path:none!important}.chart .col{transform:none!important}
  .linechart .area{transform:none!important}.linechart .line{stroke-dashoffset:0!important}.linechart .dot{opacity:1!important}

  .type-legend .row{opacity:1!important}
  .timebar{clip-path:none!important}
}

.miss{color:var(--bad);font-weight:600}

/* A code, not a word: the h1's -.03em tracking is tuned for names and
   closes up letter pairs that have to be read one character at a time. */
.head h1.mono-title{letter-spacing:-.01em;font-variant-numeric:tabular-nums}

/* ---- compliance: donut slices and source chips ---- */
/* The unfilled remainder of the ring, so a single full slice still reads
   as a proportion. Always drawn, always beneath the real arcs. */
.donut-c circle.seg-track{stroke:var(--neu-bg)}
/* Arcs and legend dots take the vivid -ico tokens, not the base ones: per the
   palette note at the top of this file the base colour is for LABEL TEXT and
   the -ico variant is the graphic. Using --ok on the ring is what made the
   donut read as a dull bottle green. */
.donut-c circle.seg-ok{stroke:var(--ok-ico)}
.donut-c circle.seg-warn{stroke:var(--warn-ico)}
.donut-c circle.seg-bad{stroke:var(--bad-ico)}
.donut-c circle.seg-neu{stroke:var(--neu-ico)}
.type-legend .dot-ok{background:var(--ok-ico)}
.type-legend .dot-warn{background:var(--warn-ico)}
.type-legend .dot-bad{background:var(--bad-ico)}
.type-legend .dot-neu{background:var(--neu-ico)}

/* ---- KPI page: card titles, headline pair, breakdown extras ---- */
.card-head{display:flex;align-items:center;gap:9px;padding:11px 20px;
  border-bottom:1px solid var(--line-2);font-size:12px;font-weight:700;letter-spacing:.04em;
  text-transform:uppercase;color:var(--sec);flex:none}
.card-head .r{margin-left:auto;font-size:12px;font-weight:500;letter-spacing:0;
  text-transform:none;color:var(--ter)}

.card-body{padding:18px 22px 20px;flex:1;display:flex;flex-direction:column;min-height:0}

/* .kpis compacted: three .kpi columns give each ~186px, where the stock 29px .v
   wraps "US$ 0,00" onto two lines. */
.kpis.sm .kpi{padding:16px 18px}
.kpis.sm .l{font-size:12px}
.kpis.sm .v{font-size:22px}
.kpis.sm .sub{font-size:12px}

/* A baseline turns "no bar" into "zero that day" instead of a hole. */
.chart.axis{border-bottom:1px solid var(--line)}

/* Shared empty state for a panel whose list came back with nothing. */
.empty-note{padding:26px 4px;text-align:center;color:var(--ter);font-size:13.5px;font-weight:500}

/* Critérios page: the same tone vocabulary the Compliance page uses
   (ok/warn/bad/neutral), applied to the shared .chip pill so a source this
   page calls healthy is never a source the Compliance page calls down. */
.chip-ok{background:var(--ok-bg);color:var(--ok)}
.chip-warn{background:var(--warn-bg);color:var(--warn)}
.chip-bad{background:var(--bad-bg);color:var(--bad)}
.chip-neutral{background:var(--neu-bg);color:var(--neu)}

.rl-count{font-size:12.5px;color:var(--ter);margin:0 0 14px}
/* The way out of an isolated criterion. Sits inline in the tally line, so
   it is styled as text with an underline rather than as another button
   competing with the filter bar right above it. */
.rl-showall{font:inherit;color:var(--accent);background:none;border:0;padding:0;text-decoration:underline;cursor:pointer}
.rl-showall:hover{color:var(--ink)}

/* ---------- Critérios: Regras tab (rule-first reading) ---------- */
/* Four levels, each a different kind of object: the family heading sits on
   the page background, the field is a card with its own head, and the rules
   inside it are a table. The heading is un-boxed on purpose — the card head
   is also a labelled bar, and two bars would compete. */
.rl-sec{display:flex;align-items:baseline;gap:12px;margin:34px 0 12px;
  font-size:19px;font-weight:700;letter-spacing:-.02em;color:var(--ink)}
.rl-sec:first-child{margin-top:6px}
.rl-sec em{font-style:normal;margin-left:auto;font-size:12.5px;font-weight:500;
  color:var(--ter)}
/* Each field is its own card inside the family: the strip is that card's head
   and the rules under it are its list, so one subject can be read without the
   neighbouring subjects running into it. */
.rl-field{margin-bottom:10px}
.rl-field:last-child{margin-bottom:0}

.rl-row{position:relative;border-bottom:1px solid var(--line-2)}
.rl-row:last-child{border-bottom:0}
/* Neutral, not accent: the expanded ground is a violet off-white, so a violet
   hover read as "this row is already open". */
.rl-row:hover{background:#F6F6F8}
.rl-row.open{background:var(--surface)}
.rl-row-off .rl-main{opacity:.55}

.rl-main{display:flex;align-items:center;gap:16px;padding:11px 18px;cursor:pointer}

/* Neutral, not accent: the expanded ground is already violet, so a violet
   hover read as "this row is already open". */
.rl-row:hover{background:#F6F6F8}
.rl-row.open:hover{background:transparent}

/* ---------- Critérios: Regras tab, read-only drawer (spec sheet) ---------- */
/* Height morph: a 0fr -> 1fr grid row animates to the drawer's natural
   height without measuring it, so nothing re-renders and nothing blinks.
   The border-top only exists while open; at 0fr it would still paint 1px. */
.rl-dw{display:grid;grid-template-rows:0fr;
  transition:grid-template-rows .3s cubic-bezier(.4,0,.2,1)}
.rl-row.open .rl-dw{grid-template-rows:1fr}

/* ---------- Critérios: Regras tab, drawer row editors (Phase 2 Task 8) ---------- */
/* The `editar` toggle on each editable row's third column; the row's own
   editor panel below it stays `hidden` until Task 9's JS flips it. */
.rl-edit{font-size:12px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;
  color:var(--accent);background:none;border:0;padding:3px 8px;border-radius:7px;
  cursor:pointer;font-family:inherit}
.rl-edit:hover{background:var(--accent-soft)}

/* A type that follows the general criticality is not an exception, so it
   stays out of the list until "+ um tipo" reveals it: a rule spanning
   twelve types would otherwise open as twelve rows of pills. */
.rl-exc-off{display:none}

.rl-ta{width:100%;margin-top:0;border:1px solid var(--line);border-radius:10px;
  padding:10px 13px;font:inherit;font-size:13px;color:var(--ink);
  background:var(--surface);resize:vertical}

.rl-commit{margin-top:18px;padding-top:16px;border-top:1px solid var(--line)}

.rl-form{overflow:hidden;min-height:0;background:var(--expanded);border:1px solid transparent;
  border-radius:var(--r);margin:0;padding:0 20px;box-shadow:var(--shadow);
  transition:padding .3s cubic-bezier(.4,0,.2,1),margin .3s cubic-bezier(.4,0,.2,1),border-color .3s ease}

.rl-empty{padding:22px;text-align:center;color:var(--ter);font-size:13px}

/* ---------- Configurações: aba Fontes ---------- */
/* Structure is borrowed from the Regras tab (.rl-sec, .rl-field, .rl-list,
   .rl-row, .rl-main, .rl-txt, .rl-n, .rl-st, .rl-chev, .rl-dw, .rl-dr,
   .rl-spec, .rl-r, .rl-edit, .rl-pills, .rl-p, .rl-commit, .rl-lab, .rl-ta,
   .rl-acts, .rl-link) and is NOT restyled here: Regras already decides how
   those look, and a second opinion is how two tabs drift apart. */
.fx-card{margin-bottom:10px}

/* Registers that never matched anybody: a list, not a queue. */
.fx-quiet{padding:16px 18px 6px}


/* ---- Windows high-contrast / forced colours ----
   Backgrounds vanish there, so the states that live in a fill get a border
   or a system colour instead. */
@media (forced-colors:active){
  .tabs a.on::after,.tabs a[aria-current="page"]::after{background:CanvasText}
  .seg a.on,.seg a[aria-current="page"]{outline:2px solid CanvasText;outline-offset:-2px}
  .st,.notice,.btn.ghost,.pag a{border:1px solid CanvasText}
  :focus-visible{outline-color:Highlight}
}

/* ---- print: the page, not the chrome ---- */
@media print{
  .bar,.skip,.page-rings,.notice-close,.pag-links,[data-menu-toggle]{display:none!important}
  body{background:#fff}
  main{max-width:none;padding:0}
  .panel,.notice{box-shadow:none;break-inside:avoid}
  .table-wrap{overflow:visible;background:none}
  .head,.summary,.toolbar,.panel,.banner,.reveal,.tile{opacity:1!important;animation:none!important}
  a[href]:not(.btn)::after{content:none}
}
