@suveren/gateway 0.30.0 → 0.31.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/content/integrations/calendar.json +3 -0
  2. package/content/integrations/crm.json +10 -0
  3. package/content/integrations/deploy-github.json +1 -0
  4. package/content/integrations/erp.json +4 -0
  5. package/content/integrations/gmail.json +4 -0
  6. package/content/integrations/linkedin.json +4 -0
  7. package/content/integrations/mail.json +1 -0
  8. package/content/integrations/mollie.json +5 -0
  9. package/content/integrations/records.json +4 -0
  10. package/dist/control-plane/index.mjs +81 -32
  11. package/dist/mcp-server/http.mjs +36 -1
  12. package/dist/ui/assets/index-B7qy0B9J.js +123 -0
  13. package/dist/ui/assets/index-DyZY5sLI.css +1 -0
  14. package/dist/ui/index.html +2 -2
  15. package/node_modules/undici/docs/docs/api/Client.md +2 -0
  16. package/node_modules/undici/lib/core/connect.js +10 -4
  17. package/node_modules/undici/lib/core/symbols.js +1 -0
  18. package/node_modules/undici/lib/dispatcher/agent.js +6 -2
  19. package/node_modules/undici/lib/dispatcher/client-h1.js +0 -2
  20. package/node_modules/undici/lib/dispatcher/client-h2.js +0 -4
  21. package/node_modules/undici/lib/dispatcher/client.js +3 -2
  22. package/node_modules/undici/lib/dispatcher/dispatcher-base.js +12 -0
  23. package/node_modules/undici/lib/handler/cache-handler.js +48 -0
  24. package/node_modules/undici/lib/handler/deduplication-handler.js +57 -13
  25. package/node_modules/undici/lib/handler/redirect-handler.js +8 -1
  26. package/node_modules/undici/lib/interceptor/decompress.js +15 -5
  27. package/node_modules/undici/lib/web/cookies/index.js +3 -1
  28. package/node_modules/undici/lib/web/cookies/parse.js +138 -137
  29. package/node_modules/undici/lib/web/cookies/util.js +21 -2
  30. package/node_modules/undici/lib/web/eventsource/eventsource-stream.js +90 -9
  31. package/node_modules/undici/lib/web/eventsource/eventsource.js +4 -1
  32. package/node_modules/undici/lib/web/fetch/index.js +3 -3
  33. package/node_modules/undici/lib/web/infra/index.js +14 -0
  34. package/node_modules/undici/lib/web/subresource-integrity/subresource-integrity.js +5 -5
  35. package/node_modules/undici/lib/web/websocket/receiver.js +13 -0
  36. package/node_modules/undici/package.json +1 -1
  37. package/node_modules/undici/types/client.d.ts +14 -0
  38. package/package.json +1 -1
  39. package/dist/ui/assets/index-C2BnlNib.js +0 -123
  40. package/dist/ui/assets/index-DPgewsLG.css +0 -1
@@ -0,0 +1 @@
1
+ :root{--text-primary: #111111;--text-secondary: #111111;--text-tertiary: #111111;--text-muted: #888888;--text-on-accent: #ffffff;--bg-main: #fafafa;--bg-elevated: #ffffff;--bg-input: #ffffff;--border: #e5e5e5;--border-strong: #c7c7c7;--accent: #888888;--accent-subtle: #f0f0f0;--accent-hover: #555555;--neutral: #111111;--neutral-subtle: #f0f0f0;--check-failed: #cd291d;--check-failed-subtle: #fef2f2;--prov-sealed: var(--text-primary);--prov-system: #1d4ed8;--prov-system-subtle: #eff6ff;--prov-ai: #b45309;--prov-ai-subtle: #fffbeb;--btn-primary-bg: #111111;--btn-primary-fg: #ffffff;--btn-primary-bg-hover: #000000;--btn-primary-bg-active: #2a2a2a;--btn-secondary-border: var(--border);--btn-outline-border-strong: var(--text-primary);--focus-ring: rgba(17, 17, 17, .35);--bg-field: #111111;--text-field: #ffffff;--border-field: #111111;--placeholder-field: rgba(255, 255, 255, .55);--field-focus-ring: rgba(0, 0, 0, .18);--elevation-0: none;--elevation-1: 0 1px 2px rgba(0, 0, 0, .06);--elevation-2: 0 4px 12px rgba(0, 0, 0, .1);--elevation-3: 0 20px 60px rgba(0, 0, 0, .25);--radius-xs: .25rem;--radius-sm: .375rem;--radius-md: .5rem;--radius-lg: .75rem;--radius-xl: 1rem;--radius-pill: 9999px;--radius-circle: 50%;--space-1: .25rem;--space-2: .5rem;--space-3: .75rem;--space-4: 1rem;--space-5: 1.25rem;--space-6: 1.5rem;--space-8: 2rem;--space-10: 2.5rem;--space-12: 3rem;--text-micro: .7rem;--text-caption: .78rem;--text-body-sm: .85rem;--text-body: .95rem;--text-lead: 1.1rem;--text-h3: 1.25rem;--text-h2: 1.5rem;--text-h1: 2rem;--text-display-page: clamp(2rem, 2.4vw, 2.5rem);--text-display-hero: clamp(2.5rem, 3.8vw, 4rem);--font-sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", sans-serif;--font-mono: "SF Mono", Monaco, "Cascadia Code", ui-monospace, Menlo, monospace;--line-tight: 1.3;--line-normal: 1.5;--line-relaxed: 1.6;--nav-height: 3.5rem;--sidebar-width: 15rem;--content-width: 75rem;--content-padding: 2rem}@media(prefers-color-scheme:dark){:root{--text-primary: #ffffff;--text-secondary: #ffffff;--text-tertiary: #ffffff;--text-muted: #9a9a9a;--text-on-accent: #000000;--bg-main: #0a0a0a;--bg-elevated: #1a1a1a;--bg-input: #141414;--border: #2a2a2a;--border-strong: #4a4a4a;--accent: #9a9a9a;--accent-subtle: #1f1f1f;--accent-hover: #bbbbbb;--neutral: #ffffff;--neutral-subtle: #1f1f1f;--check-failed: #f87171;--check-failed-subtle: #2a0a0a;--prov-system: #60a5fa;--prov-system-subtle: #0f1d33;--prov-ai: #f59e0b;--prov-ai-subtle: #2a1d06;--btn-primary-bg: #ffffff;--btn-primary-fg: #000000;--btn-primary-bg-hover: #e5e5e5;--btn-primary-bg-active: #c4c4c4;--focus-ring: rgba(255, 255, 255, .4);--bg-field: #ffffff;--text-field: #111111;--border-field: #ffffff;--placeholder-field: rgba(0, 0, 0, .5);--field-focus-ring: rgba(255, 255, 255, .25);--elevation-1: 0 1px 2px rgba(0, 0, 0, .4);--elevation-2: 0 4px 16px rgba(0, 0, 0, .5);--elevation-3: 0 20px 60px rgba(0, 0, 0, .6)}}[data-theme=dark]{--text-primary: #ffffff;--text-secondary: #ffffff;--text-tertiary: #ffffff;--text-muted: #9a9a9a;--text-on-accent: #000000;--bg-main: #0a0a0a;--bg-elevated: #1a1a1a;--bg-input: #141414;--border: #2a2a2a;--border-strong: #4a4a4a;--accent: #9a9a9a;--accent-subtle: #1f1f1f;--accent-hover: #bbbbbb;--neutral: #ffffff;--neutral-subtle: #1f1f1f;--check-failed: #f87171;--check-failed-subtle: #2a0a0a;--prov-system: #60a5fa;--prov-system-subtle: #0f1d33;--prov-ai: #f59e0b;--prov-ai-subtle: #2a1d06;--btn-primary-bg: #ffffff;--btn-primary-fg: #000000;--btn-primary-bg-hover: #e5e5e5;--btn-primary-bg-active: #c4c4c4;--focus-ring: rgba(255, 255, 255, .4);--bg-field: #ffffff;--text-field: #111111;--border-field: #ffffff;--placeholder-field: rgba(0, 0, 0, .5);--field-focus-ring: rgba(255, 255, 255, .25);--elevation-1: 0 1px 2px rgba(0, 0, 0, .4);--elevation-2: 0 4px 16px rgba(0, 0, 0, .5);--elevation-3: 0 20px 60px rgba(0, 0, 0, .6)}[data-theme=light]{--text-primary: #111111;--text-secondary: #111111;--text-tertiary: #111111;--text-muted: #888888;--text-on-accent: #ffffff;--bg-main: #fafafa;--bg-elevated: #ffffff;--bg-input: #ffffff;--border: #e5e5e5;--border-strong: #c7c7c7;--accent: #888888;--accent-subtle: #f0f0f0;--accent-hover: #555555;--neutral: #111111;--neutral-subtle: #f0f0f0;--check-failed: #cd291d;--check-failed-subtle: #fef2f2;--prov-system: #1d4ed8;--prov-system-subtle: #eff6ff;--prov-ai: #b45309;--prov-ai-subtle: #fffbeb;--btn-primary-bg: #111111;--btn-primary-fg: #ffffff;--btn-primary-bg-hover: #000000;--btn-primary-bg-active: #2a2a2a;--focus-ring: rgba(17, 17, 17, .35);--bg-field: #111111;--text-field: #ffffff;--border-field: #111111;--placeholder-field: rgba(255, 255, 255, .55);--field-focus-ring: rgba(0, 0, 0, .18);--elevation-1: 0 1px 2px rgba(0, 0, 0, .06);--elevation-2: 0 4px 12px rgba(0, 0, 0, .1);--elevation-3: 0 20px 60px rgba(0, 0, 0, .25)}@font-face{font-family:Inter;font-style:normal;font-weight:400;font-display:swap;src:url(/fonts/Inter-Regular.woff2) format("woff2")}@font-face{font-family:Inter;font-style:normal;font-weight:500;font-display:swap;src:url(/fonts/Inter-Medium.woff2) format("woff2")}@font-face{font-family:Inter;font-style:normal;font-weight:600;font-display:swap;src:url(/fonts/Inter-SemiBold.woff2) format("woff2")}@font-face{font-family:Inter;font-style:normal;font-weight:700;font-display:swap;src:url(/fonts/Inter-Bold.woff2) format("woff2")}*,*:before,*:after{margin:0;padding:0;box-sizing:border-box}html{scroll-behavior:smooth}body{font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif;font-feature-settings:"cv11","ss01","ss03";font-size:16px;line-height:1.6;color:var(--text-primary);background:var(--bg-main);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}@media(min-width:1900px){body{font-size:17.5px}}@media(min-width:2800px){body{font-size:19px}}a{color:var(--accent);text-decoration:none}a:hover{text-decoration:underline}h1,h2,h3,h4{font-weight:700;letter-spacing:-.02em;line-height:1.2;color:var(--text-primary)}code{background:var(--bg-elevated);border:1px solid var(--border);padding:.15rem .4rem;border-radius:.25rem;font-size:.875em;font-family:SF Mono,Monaco,Cascadia Code,Courier New,monospace}.top-nav{position:fixed;top:0;width:100%;height:var(--nav-height);background:color-mix(in srgb,var(--bg-main) 92%,transparent);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);border-bottom:1px solid var(--border);z-index:1000}.top-nav-inner{max-width:100%;margin:0 auto;padding:0 1.5rem;height:100%;display:flex;align-items:center;gap:1rem}.logo-group{display:flex;align-items:center;gap:.5rem;flex-shrink:0}.logo-group svg{flex-shrink:0}.logo{font-weight:700;font-size:.95rem;color:var(--text-primary);text-decoration:none}.logo:hover{text-decoration:none}.version-badge{font-size:.65rem;font-weight:600;padding:.15rem .4rem;background:var(--btn-primary-bg);color:var(--btn-primary-fg);border-radius:.25rem}.gw-version{font-size:.7rem;padding:.15rem .4rem;border-radius:.25rem;color:var(--text-muted);background:var(--accent-subtle);font-variant-numeric:tabular-nums;white-space:nowrap}.gw-version[data-stale=true]{color:var(--text-primary);background:transparent;border:1px dashed var(--text-primary)}.nav-spacer{flex:1}.nav-actions{display:flex;align-items:center;gap:.75rem}.workspace-pill{display:inline-flex;align-items:center;font-size:.75rem;font-weight:600;padding:.2rem .65rem;border-radius:9999px;border:1px solid var(--text-primary);color:var(--text-primary);white-space:nowrap}.workspace-pill[data-managed=true]{border-color:var(--accent);color:var(--accent)}.workspace-pill-it{font-weight:400}.user-chip{display:flex;align-items:center;gap:.5rem;font-size:.8rem;color:var(--text-secondary)}.user-chip strong{color:var(--text-primary)}.user-chip .dot{width:3px;height:3px;border-radius:50%;background:var(--text-tertiary)}.theme-toggle{width:2rem;height:2rem;background:none;border:1px solid var(--border);border-radius:.375rem;cursor:pointer;color:var(--text-secondary);font-size:1rem;display:flex;align-items:center;justify-content:center}.theme-toggle:hover{color:var(--accent);border-color:var(--accent)}.nav-logout{font-size:.8rem;color:var(--text-tertiary);cursor:pointer;background:none;border:none;font-family:inherit}.nav-logout:hover{color:var(--text-primary)}.domain-switcher{position:relative}.domain-switcher-btn{background:none;border:none;font-family:inherit;font-size:.8rem;color:var(--text-secondary);cursor:pointer;display:flex;align-items:center;gap:.25rem;padding:.125rem .25rem;border-radius:.25rem}.domain-switcher-btn:hover{color:var(--accent)}.domain-switcher-arrow{font-size:.6rem;color:var(--text-tertiary)}.domain-switcher-menu{position:absolute;top:calc(100% + .375rem);right:0;min-width:10rem;background:var(--bg-elevated);border:1px solid var(--border);border-radius:.5rem;box-shadow:var(--elevation-2);z-index:200;padding:.25rem}.domain-switcher-item{display:block;width:100%;text-align:left;background:none;border:none;font-family:inherit;font-size:.8rem;color:var(--text-secondary);padding:.5rem .75rem;border-radius:.375rem;cursor:pointer;white-space:nowrap}.domain-switcher-item:hover{background:var(--accent-subtle);color:var(--text-primary)}.domain-switcher-item.active{color:var(--accent);font-weight:600}.sidebar{position:fixed;top:calc(var(--nav-height) + var(--update-banner-h, 0px) + var(--sim-banner-h, 0px));left:0;width:var(--sidebar-width);height:calc(100vh - var(--nav-height) - var(--update-banner-h, 0px) - var(--sim-banner-h, 0px));background:var(--bg-elevated);border-right:1px solid var(--border);padding:1rem 0;z-index:900;display:flex;flex-direction:column}.sidebar-nav{list-style:none;padding:0 .5rem;flex:1}.sidebar-item{display:flex;align-items:center;gap:.625rem;padding:.5rem .75rem;margin-bottom:.125rem;border-radius:.5rem;font-size:.85rem;font-weight:500;color:var(--text-secondary);cursor:pointer;transition:background .15s,color .15s;text-decoration:none}.sidebar-item:hover{background:var(--accent-subtle);color:var(--text-primary);text-decoration:none}.sidebar-item.active{background:var(--accent-subtle);color:var(--accent);font-weight:600}.sidebar-item .icon{width:1.125rem;text-align:center;font-size:.9rem;flex-shrink:0}.sidebar-section-label{font-size:.65rem;font-weight:600;text-transform:uppercase;letter-spacing:.06em;color:var(--text-tertiary);padding:1rem .75rem .375rem}.sidebar-context{padding:.75rem 1rem;border-top:1px solid var(--border);font-size:.75rem;color:var(--text-tertiary)}.sidebar-context .ctx-label{font-weight:600;color:var(--text-secondary);margin-bottom:.125rem}.sidebar-context .ctx-value{color:var(--text-primary);font-weight:500}.main-content{margin-left:var(--sidebar-width);margin-top:calc(var(--nav-height) + var(--update-banner-h, 0px) + var(--sim-banner-h, 0px));padding:2rem;min-height:calc(100vh - var(--nav-height))}.main-content.no-sidebar{margin-left:0}.page-inner{max-width:56rem;margin:0 auto}.page-inner:has(.intent-layout){max-width:none}.page-header{margin-bottom:1.5rem}.page-title{font-size:1.5rem;margin-bottom:.25rem}.page-subtitle{font-size:.9rem;color:var(--text-secondary)}.btn{display:inline-flex;align-items:center;justify-content:center;gap:.5rem;padding:.625rem 1.25rem;font-size:.9rem;font-weight:500;font-family:inherit;border-radius:.5rem;border:none;cursor:pointer;transition:all .2s;text-decoration:none;line-height:1.4}.btn:disabled{opacity:.5;cursor:not-allowed}.btn-primary{background:var(--btn-primary-bg);color:var(--btn-primary-fg);border:2px solid var(--btn-primary-bg)}.btn-primary:hover:not(:disabled){background:var(--btn-primary-bg-hover);border-color:var(--btn-primary-bg-hover);color:var(--btn-primary-fg);transform:translateY(-1px);box-shadow:var(--elevation-2)}.btn-primary:active:not(:disabled){background:var(--btn-primary-bg-active);border-color:var(--btn-primary-bg-active)}.btn-secondary{background:transparent;color:var(--text-primary);border:1px solid var(--border)}.btn-secondary:hover:not(:disabled){border-color:var(--btn-primary-bg);color:var(--text-primary);background:var(--accent-subtle)}.btn-ghost{background:transparent;color:var(--text-secondary);border:none;padding:.5rem .75rem}.btn-ghost:hover:not(:disabled){color:var(--text-primary);background:var(--accent-subtle)}.btn-full{width:100%}.btn-sm{padding:.375rem .75rem;font-size:.8rem}.btn-lg{padding:.875rem 2rem;font-size:1rem;font-weight:600}.form-group{margin-bottom:1.25rem}.form-label{display:block;font-size:.875rem;font-weight:600;color:var(--text-primary);margin-bottom:.375rem}.form-input,.form-select,.form-textarea{width:100%;padding:.625rem .75rem;font-size:.9rem;font-family:inherit;color:var(--text-field);background:var(--bg-field);border:1px solid var(--border-field);border-radius:.5rem;outline:none;transition:box-shadow .2s,border-color .2s}.form-input::placeholder,.form-textarea::placeholder{color:var(--placeholder-field);opacity:1}.form-input:focus,.form-textarea:focus,.form-select:focus{box-shadow:0 0 0 3px var(--field-focus-ring)}.form-input:disabled,.form-textarea:disabled,.form-select:disabled{opacity:.55;cursor:not-allowed}.form-input-invalid,.form-input-invalid:focus{border-color:var(--border-field);box-shadow:0 0 0 2px var(--bg-elevated),0 0 0 4px var(--text-primary)}.form-textarea{resize:vertical;min-height:120px;line-height:1.5}.form-hint{font-size:.8rem;color:var(--text-tertiary);margin-top:.375rem}.form-select{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%23ffffff' d='M6 8L1 3h10z'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right .75rem center;padding-right:2.25rem}[data-theme=dark] .form-select{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%23111111' d='M6 8L1 3h10z'/%3E%3C/svg%3E")}.card{background:var(--bg-elevated);border:1px solid var(--border);border-radius:.75rem;padding:1.5rem}.card+.card{margin-top:1rem}.card-highlight{animation:hap-card-highlight 2.4s ease-out 1}@keyframes hap-card-highlight{0%{box-shadow:0 0 0 2px var(--accent),0 0 24px var(--accent-subtle);border-color:var(--accent)}60%{box-shadow:0 0 0 2px var(--accent),0 0 24px var(--accent-subtle);border-color:var(--accent)}to{box-shadow:0 0 0 0 transparent,0 0 0 transparent;border-color:var(--border)}}@media(prefers-reduced-motion:reduce){.card-highlight{animation:none;border-color:var(--accent)}}.card-header{display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:1rem}.card-title{font-size:1rem;font-weight:600;margin:0}.auth-card{background:var(--bg-elevated);border:1px solid var(--border);border-radius:.75rem;padding:1.25rem;transition:opacity .2s,border-color .2s;cursor:pointer}.auth-card:hover{border-color:var(--accent)}.auth-card+.auth-card{margin-top:.75rem}.auth-card.expired{opacity:.5}.auth-card-header{display:flex;align-items:center;gap:.75rem;margin-bottom:.5rem;flex-wrap:wrap}.auth-card-path{font-weight:600;font-size:.95rem}.auth-card-time{font-size:.8rem;color:var(--text-tertiary);margin-left:auto}.success-card{background:var(--accent-subtle);border:1px solid var(--accent);border-radius:.75rem;padding:1.5rem;text-align:center}.success-card-title{font-size:1.1rem;font-weight:700;color:var(--accent);margin-bottom:.5rem}.success-card-hash{font-family:SF Mono,Monaco,monospace;font-size:.8rem;color:var(--text-secondary);word-break:break-all;margin-bottom:.5rem}.status-badge{display:inline-block;padding:.2rem .6rem;border-radius:9999px;font-size:.7rem;font-weight:600;letter-spacing:.03em;text-transform:uppercase}.status-badge{border:1px solid transparent}.status-active{background:var(--neutral-subtle);color:var(--text-primary);border-color:var(--border)}.status-pending{background:var(--neutral);color:var(--bg-elevated);border-color:var(--neutral)}.status-pending:before{content:"○ "}.status-expired,.status-revoked,.status-refused,.status-failed{background:transparent;color:var(--text-primary);border:2px solid var(--text-primary)}.status-expired{color:var(--text-muted)}.status-expired:before,.status-revoked:before,.status-refused:before,.status-failed:before{content:"✕ "}.status-change-needed{background:transparent;color:var(--text-primary);border:1px dashed var(--text-primary)}.status-change-needed:before{content:"! "}.status-replaced,.status-passed{background:transparent;color:var(--text-primary);border-color:var(--border)}.status-replaced:before,.status-passed:before{content:"✓ "}.int-chip{display:inline-flex;align-items:center;gap:.4rem;padding:.2rem .6rem;border-radius:9999px;font-size:.7rem;font-weight:600;letter-spacing:.03em;text-transform:uppercase}.int-chip .int-dot{width:6px;height:6px;border-radius:50%;flex:none}.int-chip-ok{background:var(--neutral-subtle);color:var(--text-primary)}.int-chip-ok .int-dot{background:var(--text-primary)}.int-chip-bad{background:transparent;color:var(--text-primary);border:2px solid var(--text-primary)}.int-chip-bad .int-dot{display:none}.int-chip-bad:before{content:"✕"}.int-chip-idle{background:var(--accent-subtle);color:var(--text-muted)}.int-chip-idle .int-dot{background:var(--text-muted)}.int-chip-sim{background:transparent;color:var(--text-primary);border:1px dashed var(--text-primary)}.int-chip-sim .int-dot{background:transparent;border:1px dashed var(--text-primary)}.int-chip-paused{background:var(--bg-main);color:var(--text-muted);border:1px solid var(--border)}.int-chip-paused .int-dot{background:var(--text-muted)}.int-details{border-top:1px solid var(--border);padding-top:.7rem;margin-top:.25rem}.int-details>summary{cursor:pointer;font-size:.78rem;color:var(--text-muted);list-style:none;display:flex;align-items:center;gap:.35rem;-webkit-user-select:none;user-select:none}.int-details>summary::-webkit-details-marker{display:none}.int-details>summary:before{content:"▸";font-size:.7rem;transition:transform .15s}.int-details[open]>summary:before{transform:rotate(90deg)}.int-meta{display:grid;grid-template-columns:auto 1fr;gap:.4rem 1rem;font-size:.8rem;margin-top:.7rem}.int-meta .int-k{color:var(--text-muted)}.int-account{font-size:.85rem;display:flex;align-items:center;gap:.5rem}.int-account .int-none{color:var(--text-muted);font-style:italic}.domain-badge{display:inline-block;padding:.2rem .5rem;font-size:.8rem;font-family:SF Mono,Monaco,monospace;background:var(--bg-main);border:1px solid var(--border);border-radius:.25rem;color:var(--text-secondary)}.domain-attested{color:var(--accent);border-color:var(--accent)}.domain-missing{color:var(--text-tertiary)}.profile-badge{display:inline-block;padding:.15rem .5rem;font-size:.7rem;font-weight:600;text-transform:uppercase;letter-spacing:.03em;background:var(--accent-subtle);color:var(--accent);border-radius:.25rem}.id-card{display:flex;align-items:stretch;padding:0;overflow:hidden}.id-rail{flex:0 0 5.5rem;width:5.5rem;box-sizing:border-box;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:.4rem;padding:1rem .4rem;text-align:center}.id-rail-icon{width:1.6rem;height:1.6rem;color:var(--text-secondary);flex:none}.id-rail-name{max-width:100%;overflow-wrap:normal;word-break:keep-all;-webkit-hyphens:manual;hyphens:manual;font-size:.65rem;font-weight:700;color:var(--text-muted);line-height:1.25;text-transform:uppercase;letter-spacing:.02em}.id-sep{flex:0 0 1px;background:var(--border)}.id-body{flex:1 1 auto;min-width:0;padding:1rem 1.25rem}.id-body .auth-card-header,.id-body .receipt-head{margin-bottom:.25rem}@media(max-width:460px){.id-rail{flex-basis:4.25rem;width:4.25rem;padding:.75rem .25rem;gap:.2rem}.id-rail-icon{width:1.2rem;height:1.2rem}.id-rail-name{font-size:.5rem;letter-spacing:0}.id-body{padding:.85rem .9rem}}.profile-chip{display:inline-flex;align-items:center;gap:.45rem}.profile-chip-icon{width:1.15rem;height:1.15rem;flex:none;color:var(--text-secondary)}.sim-mark{display:inline-flex;align-items:center;gap:.3rem;font-size:.65rem;font-weight:700;text-transform:uppercase;letter-spacing:.04em;padding:.15rem .45rem;border-radius:.25rem;background:transparent;color:var(--text-primary);border:1px dashed var(--text-primary)}.wizard-progress{display:flex;align-items:flex-start;gap:.75rem;margin-bottom:2.5rem}.wizard-steps{list-style:none;margin:0;padding:0;display:flex;flex:1;max-width:28rem}.wizard-step{flex:1;display:flex;flex-direction:column;align-items:center;position:relative;min-width:0}.wizard-step:not(:first-child):before{content:"";position:absolute;top:calc(1rem - 1px);height:2px;left:calc(-50% + 1.4rem);right:calc(50% + 1.4rem);background:var(--border)}.wizard-step.reached:before{background:var(--accent)}.step-circle{width:2rem;height:2rem;border-radius:50%;display:flex;align-items:center;justify-content:center;padding:0;font-family:inherit;font-size:.75rem;font-weight:600;border:2px solid var(--border);color:var(--text-tertiary);background:var(--bg-main);flex-shrink:0;transition:all .2s;cursor:default}.step-circle.completed{background:var(--accent);border-color:var(--accent);color:var(--text-on-accent);cursor:pointer}.step-circle:disabled{cursor:default}.step-circle.current{border-color:var(--accent);color:var(--accent);box-shadow:0 0 0 3px var(--focus-ring)}.step-label-text{margin-top:.4rem;font-size:.65rem;line-height:1.2;text-align:center;color:var(--text-tertiary)}.step-label-text.completed{color:var(--text-secondary)}.step-label-text.current{color:var(--accent);font-weight:600}.wizard-cancel{flex-shrink:0;font-size:.8rem;margin-top:.15rem;margin-left:auto}.alert{padding:.75rem 1rem;border-radius:.5rem;font-size:.875rem;margin-bottom:1rem;background:var(--bg-elevated);color:var(--text-primary);border:1px solid var(--border)}.alert-error{border:2px solid var(--border-strong);font-weight:600}.alert-error:before{content:"✕ "}.alert-success:before{content:"✓ "}.nav-tabs{display:flex;gap:0;border-bottom:1px solid var(--border);margin-bottom:1.5rem}.nav-tab{padding:.75rem 1.25rem;font-size:.9rem;font-weight:500;color:var(--text-tertiary);background:none;border:none;border-bottom:2px solid transparent;cursor:pointer;transition:color .2s;margin-bottom:-1px;font-family:inherit}.nav-tab:hover{color:var(--text-primary)}.nav-tab.active{color:var(--accent);border-bottom-color:var(--accent);font-weight:600}.review-grid{display:grid;grid-template-columns:auto 1fr;gap:.5rem 1rem;font-size:.9rem;margin-bottom:1.5rem}.review-grid dt{font-weight:600;color:var(--text-secondary);padding:.25rem 0}.review-grid dd{color:var(--text-primary);padding:.25rem 0}.gate-content-block{background:var(--bg-main);border:1px solid var(--border);border-radius:.5rem;padding:1rem;font-size:.875rem;margin-bottom:1.5rem}.gate-content-item{margin-bottom:.5rem}.gate-content-item:last-child{margin-bottom:0}.gate-content-label{font-weight:600;color:var(--text-secondary);font-size:.75rem;text-transform:uppercase;letter-spacing:.04em;margin-bottom:.125rem}.gate-content-text{color:var(--text-primary);line-height:1.5}.empty-state{text-align:center;padding:3rem 1.5rem;color:var(--text-tertiary)}.empty-state-icon{font-size:2.5rem;margin-bottom:.75rem;opacity:.5}.empty-state-title{font-size:1rem;font-weight:600;color:var(--text-secondary);margin-bottom:.25rem}.empty-state-text{font-size:.875rem;color:var(--text-tertiary);margin-bottom:1rem;max-width:28rem;margin-left:auto;margin-right:auto}.login-split{margin-top:var(--nav-height);display:flex;min-height:calc(100vh - var(--nav-height))}.login-split-left{flex:1;background:var(--bg-main);display:flex;align-items:center;justify-content:center;padding:4rem 3rem}.login-split-right{flex:1;background:var(--bg-elevated);border-left:1px solid var(--border);display:flex;align-items:center;justify-content:center;padding:4rem 3rem}.login-page{display:flex;align-items:center;justify-content:center;min-height:calc(100vh - var(--nav-height));padding:2rem}.login-card{width:100%;max-width:420px}.login-header{text-align:center;margin-bottom:2rem}.login-title{font-size:1.5rem;font-weight:700;margin-bottom:.5rem}.login-subtitle{font-size:.9rem;color:var(--text-secondary);line-height:1.5}.login-divider{display:flex;align-items:center;gap:.75rem;margin:1.5rem 0;font-size:.8rem;color:var(--text-tertiary)}.login-divider:before,.login-divider:after{content:"";flex:1;height:1px;background:var(--border)}.onboarding-card{background:var(--bg-elevated);border:1px solid var(--border);border-radius:.75rem;padding:2rem;max-width:32rem;margin:0 auto}.onboarding-step{display:flex;gap:1rem;margin-bottom:1.25rem}.onboarding-step:last-child{margin-bottom:0}.onboarding-num{width:1.75rem;height:1.75rem;border-radius:50%;background:var(--accent);color:var(--text-on-accent);display:flex;align-items:center;justify-content:center;font-size:.75rem;font-weight:700;flex-shrink:0;margin-top:.1rem}.onboarding-num.done{background:var(--accent)}.onboarding-text h4{font-size:.9rem;margin-bottom:.125rem}.onboarding-text p{font-size:.825rem;color:var(--text-secondary);line-height:1.5}.selection-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(14rem,1fr));gap:.75rem;margin-bottom:1.5rem}.selection-card{background:var(--bg-elevated);border:2px solid var(--border);border-radius:.75rem;padding:1.25rem;cursor:pointer;transition:all .15s}.selection-card:hover{border-color:var(--accent);transform:translateY(-1px);box-shadow:var(--elevation-2)}.selection-card.selected{border-color:var(--accent);background:var(--accent-subtle)}.selection-card-title{font-size:1rem;font-weight:600;margin-bottom:.25rem}.selection-card-subtitle{font-size:.8rem;color:var(--text-secondary);margin-bottom:.5rem}.selection-card-id{font-size:.7rem;color:var(--text-tertiary);margin-bottom:.375rem;word-break:break-all}.selection-card-meta{display:flex;gap:.375rem;flex-wrap:wrap}.dashboard-section{margin-bottom:2rem}.section-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:1rem}.section-title{font-size:1rem;font-weight:600}.section-count{font-size:.8rem;color:var(--text-tertiary)}.ttl-badge{display:inline-flex;align-items:center;gap:.25rem;font-size:.75rem;font-weight:600;padding:.2rem .5rem;border-radius:.25rem;font-family:SF Mono,Monaco,monospace}.ttl-ok{background:var(--accent-subtle);color:var(--accent)}.ttl-warn{background:transparent;color:var(--text-primary);border:1px dashed var(--text-primary)}.quick-actions{display:grid;grid-template-columns:repeat(auto-fill,minmax(16rem,1fr));gap:.75rem;margin-bottom:2rem}.quick-action-card{background:var(--bg-elevated);border:1px solid var(--border);border-radius:.75rem;padding:1.25rem;cursor:pointer;transition:all .15s;display:flex;align-items:flex-start;gap:.875rem;text-decoration:none;color:inherit}.quick-action-card:hover{border-color:var(--accent);transform:translateY(-1px);box-shadow:var(--elevation-2);text-decoration:none}.quick-action-icon{width:2.5rem;height:2.5rem;border-radius:.5rem;background:var(--accent-subtle);color:var(--accent);display:flex;align-items:center;justify-content:center;font-size:1.25rem;flex-shrink:0}.quick-action-title{font-size:.9rem;font-weight:600;margin-bottom:.125rem}.quick-action-desc{font-size:.8rem;color:var(--text-secondary)}.pr-card{background:var(--bg-elevated);border:1px solid var(--border);border-radius:.75rem;padding:1.25rem;cursor:pointer;transition:border-color .15s}.pr-card:hover{border-color:var(--accent)}.pr-card+.pr-card{margin-top:.75rem}.pr-card-header{display:flex;align-items:center;gap:.5rem;margin-bottom:.375rem}.pr-card-repo{font-size:.75rem;color:var(--text-tertiary);font-family:SF Mono,Monaco,monospace}.pr-card-title{font-weight:600;font-size:.95rem}.pr-card-footer{display:flex;align-items:center;gap:.75rem;margin-top:.5rem;flex-wrap:wrap}.member-row{display:flex;align-items:center;gap:.75rem;padding:.75rem 0;border-bottom:1px solid var(--border)}.member-row:last-child{border-bottom:none}.member-avatar{width:2rem;height:2rem;border-radius:50%;background:var(--accent-subtle);color:var(--accent);display:flex;align-items:center;justify-content:center;font-size:.75rem;font-weight:700;flex-shrink:0}.member-info{flex:1}.member-name{font-size:.9rem;font-weight:600}.member-email{font-size:.75rem;color:var(--text-tertiary)}.member-domains{display:flex;gap:.25rem;flex-wrap:wrap}.char-counter{text-align:right;font-size:.75rem;color:var(--text-tertiary);margin-top:.25rem}.invite-input-row{display:flex;gap:.5rem}.invite-input-row .form-input{flex:1}.service-card{background:var(--bg-elevated);border:1px solid var(--border);border-radius:.75rem;padding:1.25rem;display:flex;align-items:center;gap:1rem;transition:border-color .15s}.service-card:hover{border-color:var(--accent)}.service-card+.service-card{margin-top:.75rem}.service-icon{width:2.75rem;height:2.75rem;border-radius:.625rem;display:flex;align-items:center;justify-content:center;font-size:1.25rem;flex-shrink:0}.service-icon-configured{background:var(--neutral-subtle);color:var(--text-primary)}.service-icon-missing{background:var(--bg-main);color:var(--text-tertiary);border:1px dashed var(--border)}.service-icon-error{background:transparent;color:var(--text-primary);border:2px solid var(--text-primary)}.service-info{flex:1}.service-name{font-size:.95rem;font-weight:600;margin-bottom:.125rem}.service-desc{font-size:.8rem;color:var(--text-secondary);margin-bottom:.375rem}.service-status{display:inline-flex;align-items:center;gap:.375rem;font-size:.75rem;font-weight:600}.service-status-dot{width:6px;height:6px;border-radius:50%}.service-status-connected .service-status-dot{background:var(--text-primary)}.service-status-connected{color:var(--text-primary)}.service-status-missing .service-status-dot{background:var(--text-tertiary)}.service-status-missing{color:var(--text-tertiary)}.service-status-error .service-status-dot{background:transparent;border:2px solid var(--text-primary)}.service-status-error{color:var(--text-primary)}.service-tools{display:flex;gap:.25rem;flex-wrap:wrap;margin-top:.25rem}.service-tool-badge{display:inline-block;padding:.1rem .4rem;font-size:.65rem;font-family:SF Mono,Monaco,monospace;background:var(--bg-main);border:1px solid var(--border);border-radius:.25rem;color:var(--text-tertiary)}.modal-backdrop{position:fixed;top:0;left:0;right:0;bottom:0;background:color-mix(in srgb,var(--bg-main) 70%,transparent);z-index:1500;display:flex;align-items:center;justify-content:center}.modal{background:var(--bg-elevated);border-radius:.75rem;width:100%;max-width:32rem;max-height:calc(100vh - 4rem);overflow-y:auto;box-shadow:var(--elevation-3)}.modal-header{padding:1.5rem 1.5rem 0;display:flex;justify-content:space-between;align-items:flex-start}.modal-title{font-size:1.125rem;font-weight:700}.modal-close{width:2rem;height:2rem;background:none;border:none;cursor:pointer;color:var(--text-tertiary);font-size:1.25rem;display:flex;align-items:center;justify-content:center;border-radius:.375rem}.modal-close:hover{background:var(--bg-main);color:var(--text-primary)}.modal-body{padding:1.25rem 1.5rem}.modal-footer{padding:0 1.5rem 1.5rem;display:flex;gap:.5rem;justify-content:flex-end}.status-banner{padding:.625rem 1rem;font-size:.8rem;display:flex;align-items:center;gap:.5rem;border-radius:.5rem;margin-bottom:1rem}.status-banner-warn{background:var(--accent-subtle);color:var(--accent-hover);border:1px solid var(--accent)}.status-banner-error{background:var(--bg-elevated);color:var(--text-primary);border:2px solid var(--border-strong);font-weight:600}.status-banner-success{background:var(--bg-elevated);color:var(--text-primary);border:1px solid var(--border)}.status-banner-icon{font-size:1rem;flex-shrink:0}.status-banner-text{flex:1}.status-banner a{font-weight:600}.vault-progress{display:flex;flex-direction:column;align-items:center;gap:.75rem;padding:1.5rem 0}.vault-spinner{width:2rem;height:2rem;border:3px solid var(--border);border-top-color:var(--accent);border-radius:50%;animation:spin .8s linear infinite}@keyframes spin{to{transform:rotate(360deg)}}.vault-progress-text{font-size:.875rem;color:var(--text-secondary)}.service-health-row{display:flex;align-items:center;gap:.75rem;padding:.625rem 0;border-bottom:1px solid var(--border);font-size:.85rem}.service-health-row:last-child{border-bottom:none}.service-health-indicator{width:8px;height:8px;border-radius:50%;flex-shrink:0}.service-health-indicator.connected{background:var(--text-primary)}.service-health-indicator.missing{background:var(--text-tertiary)}.service-health-indicator.error{background:transparent;border:2px solid var(--text-primary)}.service-health-name{font-weight:600;flex:1}.service-health-detail{font-size:.75rem;color:var(--text-tertiary)}.cred-field{position:relative}.cred-field .form-input{padding-right:3rem}.cred-toggle{position:absolute;right:.5rem;top:50%;transform:translateY(-50%);background:none;border:none;font-size:.75rem;color:var(--text-tertiary);cursor:pointer;padding:.25rem}.cred-toggle:hover{color:var(--accent)}.context-strip{background:var(--bg-elevated);border:1px solid var(--border);border-radius:.5rem;padding:.625rem 1rem;margin-bottom:1.5rem;display:flex;align-items:center;gap:.75rem;font-size:.8rem}.context-strip-label{font-weight:600;color:var(--text-secondary)}.timeline{position:relative;padding-left:2rem}.timeline:before{content:"";position:absolute;left:.5rem;top:0;bottom:0;width:2px;background:var(--border)}.timeline-event{position:relative;margin-bottom:1.5rem}.timeline-event:before{content:"";position:absolute;left:-1.625rem;top:.5rem;width:10px;height:10px;border-radius:50%;background:var(--accent);border:2px solid var(--bg-main)}.timeline-event.expired:before{background:var(--text-tertiary)}.error-message{padding:.75rem 1rem;background:var(--bg-elevated);border:2px solid var(--border-strong);border-radius:.5rem;color:var(--text-primary);font-weight:600;font-size:.875rem;margin-bottom:1rem}.mobile-menu-btn{display:none;width:2.25rem;height:2.25rem;background:none;border:1px solid var(--border);border-radius:.375rem;cursor:pointer;color:var(--text-secondary);font-size:1.1rem;align-items:center;justify-content:center;font-family:inherit}.mobile-menu-btn:hover{color:var(--accent);border-color:var(--accent)}.mobile-menu-backdrop{display:none;position:fixed;top:0;right:0;bottom:0;left:0;background:color-mix(in srgb,var(--bg-main) 70%,transparent);z-index:2000}.mobile-menu-panel{display:none;position:fixed;top:0;right:0;bottom:0;width:16rem;background:var(--bg-elevated);border-left:1px solid var(--border);z-index:2001;flex-direction:column;overflow-y:auto}.mobile-menu-header{padding:1.25rem 1rem;border-bottom:1px solid var(--border);display:flex;flex-direction:column;gap:.25rem}.mobile-menu-nav{flex:1;padding:.5rem;display:flex;flex-direction:column}.mobile-menu-item{display:flex;align-items:center;gap:.625rem;padding:.5rem .75rem;margin-bottom:.125rem;border-radius:.375rem;font-size:.85rem;color:var(--text-secondary);text-decoration:none;transition:background .15s,color .15s}.mobile-menu-item:hover{background:var(--accent-subtle);color:var(--text-primary)}.mobile-menu-item.active{background:var(--accent-subtle);color:var(--accent);font-weight:600}.mobile-menu-item .icon{width:1.125rem;text-align:center;font-size:.9rem;flex-shrink:0}.mobile-menu-footer{padding:.75rem 1rem;border-top:1px solid var(--border);display:flex;flex-direction:column;gap:.25rem}.mobile-menu-action{display:flex;align-items:center;gap:.625rem;padding:.5rem .75rem;border-radius:.375rem;font-size:.85rem;color:var(--text-secondary);background:none;border:none;cursor:pointer;font-family:inherit;text-align:left}.mobile-menu-action:hover{background:var(--accent-subtle);color:var(--text-primary)}.mobile-menu-action .icon{width:1.125rem;text-align:center;font-size:.9rem;flex-shrink:0}@media(max-width:768px){.sidebar{display:none}.main-content{margin-left:0}.quick-actions,.selection-grid{grid-template-columns:1fr}.nav-actions-desktop,.step-label-text{display:none}.mobile-menu-btn{display:flex}.mobile-menu-backdrop{display:block}.mobile-menu-panel{display:flex}.login-split{flex-direction:column;min-height:auto}.login-split-left{padding:3rem 1.5rem;align-items:flex-start}.login-split-right{max-width:none;border-left:none;border-top:1px solid var(--border);padding:2.5rem 1.5rem}}.update-banner{position:fixed;top:var(--nav-height);left:0;right:0;z-index:900;background:var(--bg-elevated);color:var(--text-primary);border-top:2px dashed var(--text-primary);border-bottom:2px dashed var(--text-primary);padding:.6rem 1.25rem;display:flex;flex-direction:column;gap:.6rem}.update-banner-row{display:flex;align-items:center;justify-content:space-between;gap:1rem;min-width:0}.update-banner-cmd-row{flex-wrap:wrap}.update-banner-text{font-size:.9rem;font-weight:600;color:var(--text-primary)}.update-banner-text:before{content:"! "}.update-banner-cmd{display:block;flex:1;min-width:0;font-size:.78rem;padding:.5rem .75rem;word-break:break-all;white-space:pre-wrap;background:var(--bg-main);border:1px solid var(--border-strong);border-radius:.375rem;font-family:var(--font-mono);color:var(--text-primary);-webkit-user-select:all;user-select:all}.update-banner-hint{margin:0;font-size:.8rem;color:var(--text-muted)}.update-banner-x{background:transparent;border:none;color:var(--text-muted);cursor:pointer;font-size:1.15rem;line-height:1;padding:0 .25rem}.update-banner-x:hover{color:var(--text-primary)}.update-banner.is-managed{border-top:1px solid var(--border);border-bottom:1px solid var(--border)}.update-banner.is-managed .update-banner-text:before{content:none}.update-banner.is-live{border-top:1px solid var(--border);border-bottom:1px solid var(--border)}.update-banner.is-live .update-banner-text:before{content:"✓ "}.simulation-banner{position:fixed;top:calc(var(--nav-height) + var(--update-banner-h, 0px));left:0;right:0;z-index:899;background:var(--bg-elevated);color:var(--text-primary);border-top:2px dashed var(--text-primary);border-bottom:2px dashed var(--text-primary);padding:.6rem 1.25rem;text-align:center}.simulation-banner-text{font-size:.9rem;font-weight:600}.it-locked-badge{display:inline-flex;align-items:center;gap:.3rem;font-size:.68rem;font-weight:700;text-transform:uppercase;letter-spacing:.04em;color:var(--text-secondary);background:var(--accent-subtle);border:1px solid var(--border);border-radius:999px;padding:.2rem .55rem;white-space:nowrap}.it-locked-badge .lock-icon{font-size:.75rem}body.is-updating .top-nav,body.is-updating .sidebar,body.is-updating .main-content,body.is-updating .update-banner,body.is-updating .simulation-banner{filter:blur(5px);pointer-events:none;-webkit-user-select:none;user-select:none}.update-overlay{position:fixed;top:0;right:0;bottom:0;left:0;z-index:2000;display:flex;align-items:center;justify-content:center;background:color-mix(in srgb,var(--bg-main) 70%,transparent);padding:1rem}.update-overlay-card{background:var(--bg-elevated);border:1px solid var(--border);border-radius:1rem;padding:2rem 2.25rem;max-width:460px;width:100%;text-align:center;box-shadow:var(--elevation-3)}.update-overlay-card h2{margin:0 0 .6rem;font-size:1.15rem}.update-overlay-card p{margin:0 0 .5rem;font-size:.88rem;color:var(--text-muted);line-height:1.55}.update-spinner{width:2.25rem;height:2.25rem;border:3px solid var(--border);border-top-color:var(--text-primary);border-radius:50%;margin:0 auto 1.1rem;animation:update-spin 1s linear infinite}@keyframes update-spin{to{transform:rotate(360deg)}}.update-cmd-row{display:flex;gap:.5rem;align-items:flex-start;margin:.9rem 0;text-align:left}.update-cmd{flex:1;min-width:0;font-size:.78rem;padding:.6rem .75rem;background:var(--bg-field);color:var(--text-field);border-radius:.45rem;font-family:SF Mono,Fira Code,Fira Mono,Menlo,Consolas,monospace;word-break:break-all;white-space:pre-wrap}.update-status{font-size:.8rem;color:var(--text-muted);margin:.4rem 0 1.1rem;display:flex;align-items:center;justify-content:center;gap:.4rem}.update-pulse{width:.55rem;height:.55rem;border-radius:50%;background:var(--text-primary);animation:update-pulse 1.2s ease infinite}@keyframes update-pulse{0%,to{opacity:.3}50%{opacity:1}}.update-overlay-actions{display:flex;gap:.6rem;justify-content:center}.search-filter-bar{display:flex;gap:.5rem;margin-bottom:.75rem}.search-input-wrap{flex:1;position:relative}.search-icon{position:absolute;left:.75rem;top:50%;transform:translateY(-50%);color:var(--text-tertiary);font-size:1rem;pointer-events:none}.search-input{padding-left:2.25rem!important;padding-right:2rem!important}.search-clear{position:absolute;right:.5rem;top:50%;transform:translateY(-50%);background:none;border:none;color:var(--text-tertiary);font-size:1.1rem;cursor:pointer;padding:.25rem;line-height:1}.search-clear:hover{color:var(--text-primary)}.filter-panel{background:var(--bg-elevated);border:1px solid var(--border);border-radius:.5rem;padding:1rem;margin-bottom:.75rem;display:flex;flex-direction:column;gap:.75rem}.filter-section{display:flex;align-items:baseline;gap:.75rem}.filter-label{font-size:.75rem;font-weight:600;color:var(--text-tertiary);text-transform:uppercase;letter-spacing:.04em;min-width:5rem;flex-shrink:0}.filter-chips{display:flex;flex-wrap:wrap;gap:.375rem}.filter-chip{font-family:inherit;font-size:.8rem;padding:.3rem .625rem;border-radius:1rem;border:1px solid var(--border);background:var(--bg-main);color:var(--text-secondary);cursor:pointer;transition:all .15s}.filter-chip:hover{border-color:var(--accent);color:var(--text-primary)}.filter-chip.selected{background:var(--accent-subtle);border-color:var(--accent);color:var(--accent);font-weight:600}.active-filters{display:flex;flex-wrap:wrap;align-items:center;gap:.375rem;margin-bottom:.75rem}.active-chip{display:inline-flex;align-items:center;gap:.25rem;font-size:.75rem;padding:.2rem .5rem;border-radius:1rem;background:var(--accent-subtle);color:var(--accent);cursor:pointer;transition:background .15s}.active-chip:hover{background:var(--accent);color:var(--bg-elevated)}.chip-remove{font-size:.85rem;line-height:1}.clear-filters{font-family:inherit;font-size:.75rem;color:var(--text-tertiary);background:none;border:none;cursor:pointer;padding:.2rem 0}.clear-filters:hover{color:var(--text-primary)}.receipt-action{display:inline-block;font-size:.75rem;font-weight:600;padding:.15rem .5rem;border-radius:1rem;background:var(--bg-main);border:1px solid var(--border);color:var(--text-secondary);font-family:SF Mono,Monaco,monospace}.bounds-section,.context-section{background:var(--bg-elevated);border:2px solid var(--border-strong);border-radius:.75rem;padding:1.25rem;margin-bottom:1.25rem;transition:border-color .15s}.bounds-section:hover,.bounds-section:focus-within,.context-section:hover,.context-section:focus-within{border-color:var(--accent-hover)}.bounds-section-header{display:flex;align-items:flex-start;gap:.625rem;margin-bottom:1rem}.bounds-section-icon{font-size:1.1rem;flex-shrink:0;margin-top:.1rem}.bounds-section-title{font-size:.9rem;font-weight:700;color:var(--text-primary)}.bounds-section-subtitle{font-size:.75rem;color:var(--text-tertiary)}.bounds-fields-grid{display:flex;flex-direction:column;gap:.75rem}.bounds-field-row{display:flex;flex-direction:row;align-items:center;justify-content:space-between;gap:1rem;width:100%}.bounds-field-label{flex:1;min-width:0}.bounds-field-label .form-label{display:inline;margin-bottom:0}.bounds-field-input{flex-shrink:0;display:flex;flex-direction:column;align-items:flex-end}.bounds-field-input .bounded-input{align-items:flex-end}.bounds-field-input .bounded-input-presets{justify-content:flex-end}.bounds-field-label-inline{display:flex;align-items:center;gap:.375rem;margin-bottom:.375rem}.bounds-field-label-inline .form-label{margin-bottom:0}.field-info-toggle{display:inline-flex;align-items:center;justify-content:center;width:1.125rem;height:1.125rem;border-radius:50%;border:1px solid var(--border);background:var(--bg-main);color:var(--text-tertiary);font-size:.65rem;font-weight:700;cursor:pointer;flex-shrink:0;transition:color .15s,border-color .15s;font-family:inherit;line-height:1;padding:0}.field-info-toggle:hover{color:var(--accent);border-color:var(--accent)}.field-description{margin-top:.25rem;margin-bottom:.25rem}@media(max-width:768px){.bounds-field-row{flex-direction:column;gap:.375rem}}.cap-note{display:block;font-size:.72rem;line-height:1.4}.cap-note.hard{color:var(--text-primary);font-weight:700}.cap-note.soft{color:var(--text-primary)}.cap-note.soft:before{content:"! ";font-weight:700}.bounded-input{display:flex;flex-direction:column;align-items:flex-start;gap:.375rem}.bounded-input-field{display:inline-flex;align-items:stretch;border:1px solid var(--border-field);border-radius:.5rem;overflow:hidden;background:var(--bg-field);color:var(--text-field)}.stepper-btn{display:flex;align-items:center;justify-content:center;width:2.25rem;height:2.25rem;background:transparent;border:none;cursor:pointer;font-size:1.1rem;font-weight:600;color:var(--text-field);font-family:inherit;flex-shrink:0;transition:background .15s}.stepper-btn:hover:not(:disabled){background:var(--placeholder-field)}.stepper-btn:disabled{opacity:.35;cursor:not-allowed}.stepper-input{width:4.5rem;text-align:center;border:none;border-left:1px solid var(--placeholder-field);border-right:1px solid var(--placeholder-field);padding:.5rem .25rem;font-size:.9rem;font-family:inherit;color:var(--text-field);background:var(--bg-field);outline:none;-moz-appearance:textfield}.stepper-input::-webkit-outer-spin-button,.stepper-input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}.stepper-input:focus{box-shadow:inset 0 0 0 2px var(--field-focus-ring)}.bounded-input-unit{display:inline-flex;align-items:center;padding:0 .75rem;font-size:.8rem;color:var(--text-field);opacity:.7;white-space:nowrap;-webkit-user-select:none;user-select:none;background:transparent}.bounded-input-presets{display:flex;flex-wrap:wrap;gap:.25rem}.preset-chip{font-family:inherit;font-size:.75rem;padding:.2rem .625rem;border:1px solid var(--border);border-radius:999px;background:transparent;color:var(--text-secondary);cursor:pointer;transition:background .15s,color .15s,border-color .15s}.preset-chip:hover{background:var(--accent-subtle);color:var(--accent);border-color:var(--accent)}.preset-chip-selected{background:var(--accent);color:var(--bg-main);border-color:var(--accent)}.bounded-input-echo{font-size:.75rem;color:var(--text-secondary);font-style:italic}.field-label-with-tip{display:inline-flex;align-items:center;gap:.375rem;position:relative}.field-tip-trigger{display:inline-flex;align-items:center;justify-content:center;width:1.125rem;height:1.125rem;border-radius:999px;border:1px solid var(--border);background:transparent;color:var(--text-secondary);font-size:.7rem;font-style:italic;font-family:serif;font-weight:600;line-height:1;cursor:help;padding:0}.field-tip-trigger:hover,.field-tip-trigger[aria-expanded=true]{border-color:var(--accent);color:var(--accent)}.field-tip-bubble{position:absolute;top:calc(100% + .375rem);left:0;z-index:10;width:max-content;max-width:22rem;padding:.5rem .75rem;background:var(--bg-elevated);border:1px solid var(--border);border-radius:.375rem;font-size:.8rem;color:var(--text-primary);line-height:1.45;box-shadow:var(--elevation-2);pointer-events:none}.tag-input{display:flex;flex-wrap:wrap;align-items:center;gap:.375rem;padding:.375rem .5rem;background:var(--bg-field);border:1px solid var(--border-field);border-radius:.5rem;cursor:text;min-height:2.5rem;transition:box-shadow .2s,border-color .2s;color:var(--text-field)}.tag-input:focus-within{box-shadow:0 0 0 3px var(--field-focus-ring)}.tag-input-invalid,.tag-input-invalid:focus-within{box-shadow:0 0 0 2px var(--bg-elevated),0 0 0 4px var(--text-primary)}.tag-pill{display:inline-flex;align-items:center;gap:.25rem;font-size:.8rem;padding:.2rem .5rem;border-radius:1rem;background:var(--placeholder-field);color:var(--text-field);font-weight:500;white-space:nowrap}.tag-remove{display:inline-flex;align-items:center;justify-content:center;background:none;border:none;font-size:.9rem;line-height:1;color:var(--text-field);cursor:pointer;padding:0;margin-left:.125rem;opacity:.7;transition:opacity .15s}.tag-remove:hover{opacity:1}.tag-input-field{flex:1;min-width:8rem;border:none;outline:none;background:transparent;font-size:.875rem;font-family:inherit;color:var(--text-field);padding:.2rem 0}.tag-input-field::placeholder{color:var(--placeholder-field);opacity:1}.checkbox-group{display:flex;flex-wrap:wrap;gap:.5rem}.checkbox-pill{display:inline-flex;align-items:center;gap:.35rem;font-size:.85rem;padding:.35rem .75rem;border-radius:1rem;border:1px solid var(--border);background:var(--bg-main);color:var(--text-secondary);cursor:pointer;transition:all .15s;-webkit-user-select:none;user-select:none}.checkbox-pill input[type=checkbox]{display:none}.checkbox-pill:hover{border-color:var(--accent);color:var(--text-primary)}.checkbox-pill-selected{background:var(--btn-primary-bg);border-color:var(--btn-primary-bg);color:var(--btn-primary-fg);font-weight:500}.checkbox-pill-selected:hover{background:var(--btn-primary-bg-hover);border-color:var(--btn-primary-bg-hover);color:var(--btn-primary-fg)}@keyframes hap-skeleton-shimmer{0%{background-position:200% 0}to{background-position:-200% 0}}.skeleton{display:block;position:relative;border-radius:.375rem;background-color:var(--bg-main);background-image:linear-gradient(90deg,transparent 0%,color-mix(in srgb,var(--text-primary) 3%,transparent) 20%,color-mix(in srgb,var(--text-primary) 8%,transparent) 50%,color-mix(in srgb,var(--text-primary) 3%,transparent) 80%,transparent 100%);background-size:200% 100%;background-repeat:no-repeat;animation:hap-skeleton-shimmer 1.6s ease-in-out infinite;will-change:background-position}.skeleton-title{height:1.5rem;width:3rem;margin:0 auto}.skeleton-line{height:.75rem;width:100%}.skeleton-line-sm{height:.65rem;width:60%}.skeleton-card{background:var(--bg-elevated);border:1px solid var(--border);border-radius:.5rem;padding:.75rem 1rem;box-shadow:var(--elevation-1);display:flex;align-items:center;gap:.75rem}.skeleton-dot{width:.5rem;height:.5rem;border-radius:50%;flex-shrink:0}@media(prefers-reduced-motion:reduce){.skeleton{animation:none;background-image:none}}.intent-layout{display:grid;grid-template-columns:minmax(320px,1fr) minmax(420px,1.4fr);gap:1.25rem;align-items:start}.intent-layout.no-chat{grid-template-columns:minmax(0,1fr);max-width:56rem}.intent-ai-hint{margin:.5rem 0 0;font-size:.8rem;color:var(--text-tertiary)}.intent-pane.chat{display:flex;flex-direction:column;gap:.75rem;position:sticky;top:1rem;align-self:start;max-height:calc(100vh - 4rem)}.intent-pane.document{display:flex;flex-direction:column;gap:.875rem}.intent-pane .card-title{font-size:1.25rem;margin:0 0 1rem}.intent-textarea{width:100%;background:var(--bg-field);border:1px solid var(--border-field);border-radius:.5rem;padding:.625rem .75rem;color:var(--text-field);font-size:.9rem;line-height:1.5;resize:vertical;min-height:22rem;outline:none;font-family:inherit;transition:box-shadow .15s}.intent-textarea:focus{box-shadow:0 0 0 3px var(--field-focus-ring)}.intent-textarea::placeholder{color:var(--placeholder-field);opacity:1}.intent-footer{display:flex;align-items:center;gap:.625rem;margin-top:.5rem}.intent-continue-btn{flex:1}.intent-chat{display:flex;flex-direction:column;gap:.75rem;flex:1;min-height:0}.intent-chat .chat-header{font-size:.72rem;font-weight:700;text-transform:uppercase;letter-spacing:.07em;color:var(--text-muted)}.intent-chat .chat-messages{flex:1;overflow-y:auto;position:relative;display:flex;flex-direction:column;gap:1rem;padding:.25rem 0;min-height:14rem;max-height:32rem}.intent-chat .chat-msg{display:flex;max-width:100%}.intent-chat .chat-msg.assistant{justify-content:flex-start}.intent-chat .chat-msg.assistant .chat-msg-body{max-width:100%;color:var(--text-primary);font-size:.9rem;line-height:1.65;white-space:pre-wrap;word-break:break-word}.intent-chat .chat-msg.user{justify-content:flex-end}.intent-chat .chat-msg.user .chat-msg-body{max-width:85%;background:var(--bg-main);border:1px solid var(--border);border-radius:1.125rem;padding:.55rem .875rem;color:var(--text-primary);font-size:.9rem;line-height:1.55;white-space:pre-wrap;word-break:break-word}.intent-chat .chat-msg-prose{white-space:pre-wrap;word-break:break-word}.intent-chat .chat-msg-thinking{color:var(--text-muted);font-style:italic}.intent-chat .chat-fenced-block{display:block;background:var(--bg-elevated);border:1px solid var(--border);border-radius:.5rem;padding:.625rem .75rem;margin:.5rem 0;font-family:SF Mono,Monaco,Cascadia Code,monospace;font-size:.8rem;white-space:pre-wrap;color:var(--text-primary);line-height:1.55}.intent-chat .chat-apply-btn{margin-top:.5rem}.intent-chat .chat-composer{display:flex;flex-direction:column;gap:.375rem}.intent-chat .chat-composer-pill{display:flex;align-items:center;gap:.5rem;background:var(--bg-field);border:1px solid var(--border-field);border-radius:1.5rem;padding:.25rem .25rem .25rem 1rem;transition:box-shadow .15s;color:var(--text-field)}.intent-chat .chat-composer-pill:focus-within{box-shadow:0 0 0 3px var(--field-focus-ring)}.intent-chat .chat-input{flex:1;resize:none;background:transparent;border:none;padding:.5rem 0;color:var(--text-field);font-size:.9rem;line-height:1.4;outline:none;font-family:inherit;max-height:8rem;align-self:stretch}.intent-chat .chat-input::placeholder{color:var(--placeholder-field);opacity:1}.intent-chat .chat-send-btn{flex-shrink:0;width:2rem;height:2rem;border-radius:999px;background:var(--text-field);color:var(--bg-field);border:none;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;font-size:1rem;font-weight:700;line-height:1;align-self:center;transition:opacity .15s,transform .1s}.intent-chat .chat-send-btn:hover:not(:disabled){opacity:.85}.intent-chat .chat-send-btn:active:not(:disabled){transform:scale(.95)}.intent-chat .chat-send-btn:disabled{opacity:.35;cursor:not-allowed}.intent-chat .chat-composer-hint{font-size:.72rem;color:var(--text-muted);padding-left:.5rem}.hint-box{display:flex;gap:.625rem;padding:.75rem .875rem;background:var(--bg-main);border:1px solid var(--border);border-left:3px solid var(--accent);border-radius:.5rem;font-size:.85rem;color:var(--text-primary);line-height:1.55;margin-top:.25rem}.hint-icon{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:1.125rem;height:1.125rem;border-radius:999px;border:1px solid var(--accent);color:var(--accent);font-size:.7rem;font-style:italic;font-family:serif;font-weight:700;line-height:1;margin-top:.125rem}.hint-body{flex:1;min-width:0}.hint-head{font-weight:600;margin-bottom:.25rem}@media(max-width:1024px){.intent-layout{grid-template-columns:1fr}.intent-pane.chat{position:static;max-height:none}}@media(max-width:768px){.intent-layout>.intent-pane.chat{display:none}.floating-help{display:inline-flex}}.floating-help{display:none;align-items:center;gap:.5rem;position:fixed;bottom:1rem;right:1rem;z-index:5;background:var(--btn-primary-bg);color:var(--btn-primary-fg);border:2px solid var(--btn-primary-bg);border-radius:999px;padding:.625rem 1.125rem;font-weight:700;font-size:.85rem;cursor:pointer;font-family:inherit;box-shadow:var(--elevation-2)}.floating-help:hover{background:var(--btn-primary-bg-hover);border-color:var(--btn-primary-bg-hover)}.bottom-sheet{position:fixed;left:0;right:0;bottom:0;height:88vh;background:var(--bg-elevated);border-top:1px solid var(--border);border-radius:.75rem .75rem 0 0;z-index:11;padding:1rem 1rem 1.25rem;overflow-y:auto;display:flex;flex-direction:column;gap:.75rem;transform:translateY(100%);transition:transform .25s ease-out;box-shadow:var(--elevation-3);outline:none}.bottom-sheet.is-open{transform:translateY(0)}.bottom-sheet-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;background:color-mix(in srgb,var(--bg-main) 70%,transparent);z-index:10;opacity:0;pointer-events:none;transition:opacity .2s}.bottom-sheet-backdrop.is-open{opacity:1;pointer-events:auto}.bottom-sheet-handle{width:2.5rem;height:.25rem;background:var(--text-muted);border-radius:999px;margin:0 auto .5rem;flex-shrink:0}.bottom-sheet-close{position:absolute;top:.5rem;right:.875rem;background:transparent;border:none;color:var(--text-primary);cursor:pointer;font-size:1.5rem;line-height:1;font-family:inherit}@media(prefers-reduced-motion:reduce){.bottom-sheet,.bottom-sheet-backdrop{transition:none}}.field-editable{background:var(--bg-elevated);border:2px solid var(--border-strong);border-radius:.5rem;padding:.875rem 1rem;margin-bottom:1rem;transition:border-color .15s}.field-editable:hover,.field-editable:focus-within{border-color:var(--accent-hover)}.field-label{font-size:.7rem;font-weight:600;text-transform:uppercase;letter-spacing:.05em;color:var(--text-tertiary);margin-bottom:.5rem;display:flex;align-items:center;gap:.35rem}.field-label .pen{opacity:.7;font-size:.75rem}.info-block{background:var(--bg-main);border-left:3px solid var(--border);border-radius:0 .375rem .375rem 0;padding:.75rem 1rem;margin-bottom:.75rem;font-size:.85rem;color:var(--text-secondary)}.info-head{display:flex;justify-content:space-between;align-items:baseline;margin-bottom:.4rem}.info-title{font-size:.7rem;font-weight:600;text-transform:uppercase;letter-spacing:.05em;color:var(--text-tertiary)}.info-edit{font-size:.72rem;color:var(--text-tertiary);text-decoration:underline;cursor:pointer;background:none;border:none;font-family:inherit;padding:0}.info-edit:hover{color:var(--accent-hover)}.info-kv{display:grid;grid-template-columns:max-content 1fr;gap:.15rem 1rem;margin:0}.info-kv dt{color:var(--text-tertiary)}.info-kv dd{margin:0;color:var(--text-secondary);word-break:break-word}.info-section-label{margin:1.25rem 0 .5rem;font-size:.7rem;font-weight:600;text-transform:uppercase;letter-spacing:.05em;color:var(--text-tertiary)}.intent-pane.chat.tool{background:var(--bg-main);border:1px dashed var(--border)}.recent-blocks .card-header{margin-bottom:.35rem}.recent-blocks .rb-sub{color:var(--text-muted);font-size:.8rem;margin:0 0 1.1rem;line-height:1.45;max-width:36ch}.recent-blocks .rb-count,.attention .rb-count{flex:none;min-width:1.6rem;height:1.6rem;padding:0 .45rem;display:inline-flex;align-items:center;justify-content:center;font-size:.8rem;font-weight:600;font-variant-numeric:tabular-nums;background:var(--neutral);color:var(--bg-elevated);border-radius:var(--radius-pill)}.recent-blocks .rb-rows{display:flex;flex-direction:column}.recent-blocks .rb-row{display:grid;grid-template-columns:auto 1fr auto;gap:.75rem .85rem;align-items:start;padding:.85rem 0;border-top:1px solid var(--border)}.recent-blocks .rb-row:first-child{border-top:none}.recent-blocks .rb-dot{width:.5rem;height:.5rem;border-radius:var(--radius-circle);margin-top:.35rem;background:var(--text-primary)}.recent-blocks .rb-dot.info{background:var(--text-muted)}.recent-blocks .rb-body{min-width:0}.recent-blocks .rb-line{font-size:.86rem;line-height:1.4;color:var(--text-primary)}.recent-blocks .rb-line b{font-weight:600}.recent-blocks .rb-meta{display:flex;align-items:center;gap:.5rem;margin-top:.3rem;flex-wrap:wrap}.recent-blocks .rb-chip{font-size:.64rem;letter-spacing:.06em;text-transform:uppercase;font-weight:600;padding:.12rem .44rem;border-radius:.35rem;background:var(--accent-subtle);color:var(--text-muted)}.recent-blocks .rb-chip.warn{background:transparent;color:var(--text-primary);border:1px dashed var(--text-primary)}.recent-blocks .rb-chip.act{background:transparent;color:var(--text-primary);border:2px solid var(--text-primary)}.recent-blocks .rb-via{font-size:.72rem;color:var(--text-muted)}.recent-blocks .rb-when{font-size:.74rem;color:var(--text-muted);font-variant-numeric:tabular-nums;white-space:nowrap;text-align:right}.recent-blocks .rb-fix{display:inline-block;margin-top:.4rem;font-size:.76rem;color:var(--text-primary);text-underline-offset:2px}.recent-blocks .rb-foot{margin-top:1rem;padding-top:.9rem;border-top:1px solid var(--border)}.recent-blocks .rb-viewall{font:inherit;font-size:.8rem;color:var(--text-primary);background:none;border:none;padding:0;cursor:pointer;text-decoration:underline;text-underline-offset:3px}.recent-blocks .rb-empty,.all-clear{text-align:center;padding:1.25rem 1rem .25rem}.blocked-header{display:flex;align-items:baseline;justify-content:space-between;gap:1rem}.blocked-today{font-size:.85rem;color:var(--text-muted);white-space:nowrap}.blocked-list{display:flex;flex-direction:column}.blocked-row-head{display:flex;align-items:center;gap:.5rem;flex-wrap:wrap;margin-bottom:.2rem}.blocked-dot{width:.5rem;height:.5rem;border-radius:var(--radius-circle);flex:none;background:var(--text-primary)}.blocked-dot-simulation{background:var(--text-muted)}.blocked-item[data-seen=true] .blocked-dot{background:transparent;border:1.5px solid var(--text-primary)}.blocked-item[data-seen=true] .blocked-dot-simulation{border-color:var(--text-muted)}.blocked-title{font-weight:600;font-size:.92rem}.new-pill{font-size:.6rem;font-weight:700;text-transform:uppercase;letter-spacing:.04em;padding:.1rem .4rem;border-radius:.25rem;background:var(--accent-subtle);color:var(--accent);flex:none}.blocked-when{margin-left:auto;font-size:.74rem;color:var(--text-muted);white-space:nowrap}.blocked-sentence{font-size:.86rem;color:var(--text-primary);line-height:1.4;margin-bottom:.3rem}.blocked-source{font-size:.74rem;color:var(--text-muted);line-height:1.5}.mandate-id{color:var(--text-muted);opacity:.65;font-size:.95em}.blocked-item details{margin-top:.4rem;font-size:.8rem}.blocked-item summary{cursor:pointer;color:var(--text-muted)}.blocked-advice{margin-top:.3rem;color:var(--text-secondary)}@media(max-width:460px){.blocked-when{margin-left:0;flex-basis:100%;order:3}}.attention .card-header{margin-bottom:.5rem}.attention-rows{display:flex;flex-direction:column}.attention-row{display:flex;align-items:center;gap:.75rem;padding:.7rem 0;border-top:1px solid var(--border);text-decoration:none;color:inherit}.attention-row:first-child{border-top:none}.attention-row:hover{background:var(--accent-subtle)}.attention-row:focus-visible{outline:2px solid var(--focus-ring);outline-offset:2px}.attention-dot{width:.5rem;height:.5rem;border-radius:50%;flex-shrink:0}.recent-blocks .rb-mark,.all-clear .rb-mark{width:2.25rem;height:2.25rem;border-radius:var(--radius-circle);background:var(--neutral-subtle);color:var(--text-primary);display:inline-flex;align-items:center;justify-content:center;margin-bottom:.75rem}.recent-blocks .rb-empty h3,.all-clear h3{font-size:.9rem;margin:0 0 .3rem}.recent-blocks .rb-empty p,.all-clear p{font-size:.8rem;color:var(--text-muted);margin:0 auto;max-width:30ch;line-height:1.45}.sim-paused-summary{display:flex;align-items:flex-start;gap:.6rem;color:var(--text-secondary);background:var(--bg-elevated);border:1px dashed var(--border);border-radius:.625rem;padding:.75rem 1rem;font-size:.82rem;line-height:1.5;margin-bottom:1.5rem}.sim-paused-summary-icon{flex-shrink:0}.sim-paused-summary b{color:var(--text-primary)}.int-group-label{font-size:.7rem;font-weight:600;letter-spacing:.05em;text-transform:uppercase;color:var(--text-muted);margin:1.5rem 0 .6rem}.int-group-label:first-child{margin-top:0}.int-paused-group{background:var(--bg-elevated);border:1px solid var(--border);border-radius:.75rem;padding:.85rem 1rem 1rem;margin-bottom:1rem}.int-paused-group>summary{cursor:pointer;font-weight:600;font-size:.85rem;color:var(--text-primary);list-style:none;display:flex;align-items:center;gap:.35rem;-webkit-user-select:none;user-select:none}.int-paused-group>summary::-webkit-details-marker{display:none}.int-paused-group>summary:before{content:"▸";color:var(--text-muted)}.int-paused-group[open]>summary:before{content:"▾"}.int-paused-group-note{color:var(--text-muted);font-size:.78rem;margin:.55rem 0 .2rem;line-height:1.55}.int-paused-group-note code{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:.76rem}.int-paused-row{display:flex;align-items:center;gap:.7rem;padding:.55rem 0;border-top:1px solid var(--border)}.int-paused-row:first-of-type{border-top:0;margin-top:.3rem}.int-paused-row .int-paused-name{font-weight:500;flex:1;font-size:.85rem;min-width:0}.receipt-head{display:flex;align-items:center;gap:.5rem;flex-wrap:wrap}.receipt-what{font-size:.95rem;font-weight:600;letter-spacing:-.01em;color:var(--text-primary)}.receipt-tag{font-size:.68rem;padding:.12rem .4rem;border-radius:4px;border:1px solid var(--border);color:var(--text-muted);white-space:nowrap}.receipt-tag-bound{color:var(--prov-sealed);border-color:var(--prov-sealed);font-weight:600}.receipt-scope{font-size:.82rem;color:var(--text-muted);margin-top:.2rem}.receipt-foot{display:flex;align-items:center;gap:.75rem;flex-wrap:wrap;margin-top:.55rem;padding-top:.55rem;border-top:1px solid var(--border)}.receipt-link{font-size:.78rem;color:var(--text-secondary);text-decoration:none;border-bottom:1px solid var(--border)}.receipt-link:hover{color:var(--accent-hover);border-color:var(--accent-hover)}.receipt-id{font-family:SF Mono,Monaco,monospace;font-size:.7rem;color:var(--text-muted)}.receipt-more{margin-top:.5rem}.receipt-more summary{cursor:pointer;font-size:.75rem;color:var(--text-muted);list-style:none}.receipt-more summary::-webkit-details-marker{display:none}.receipt-more summary:before{content:"▸"}.receipt-more[open] summary:before{content:"▾"}.receipt-kv{font-size:.72rem;color:var(--text-muted);margin-top:.4rem;line-height:1.7;font-family:SF Mono,Monaco,monospace;word-break:break-all}.receipt-rows{display:grid;grid-template-columns:7.5rem 1fr;row-gap:.35rem;column-gap:1rem;font-size:.8rem;margin:.8rem 0 0;padding-top:.7rem;border-top:1px solid var(--border)}.receipt-row-label{color:var(--text-muted);margin:0}.receipt-row-value{margin:0;overflow-wrap:anywhere}.receipt-num{font-variant-numeric:tabular-nums}.receipt-intent{font-style:italic;line-height:1.55}.receipt-absent{color:var(--text-muted)}@media(max-width:480px){.receipt-rows{grid-template-columns:1fr;row-gap:.15rem}.receipt-row-label{margin-top:.35rem}}.receipt-evidence-link{font-size:.78rem;font-weight:500;color:var(--text-primary);background:none;border:none;border-bottom:1px solid var(--border);padding:0;cursor:pointer;font-family:inherit}.receipt-evidence-link:hover{border-color:var(--text-primary)}.receipt-public{margin-left:auto;font-size:.76rem;color:var(--text-muted)}.receipt-verified{font-size:.76rem;font-weight:600;color:var(--text-primary)}.receipt-tamper{font-size:.76rem;font-weight:700;color:var(--text-primary);border:2px solid var(--text-primary);border-radius:var(--radius-xs);padding:0 .3rem}.page-inner:has(.reports-layout){max-width:none}.reports-bar{display:flex;justify-content:space-between;align-items:flex-start;gap:1rem;flex-wrap:wrap;margin-bottom:1rem}.reports-bar-actions{display:flex;gap:.5rem;align-items:center;flex-shrink:0}.reports-grid{display:grid;grid-template-columns:1fr 320px;gap:1.5rem;align-items:start}.reports-side>*+*{margin-top:.75rem}.reports-row{display:flex;justify-content:space-between;gap:.75rem;padding:.3rem 0;border-bottom:1px solid var(--border);font-size:.85rem}.reports-row:last-child{border-bottom:none}.reports-missing{margin-top:.5rem;padding:.5rem .75rem;background:var(--accent-subtle);border-radius:.5rem;font-size:.8rem;color:var(--text-primary)}.reports-error{margin:.3rem 0;padding:.5rem .75rem;background:var(--bg-elevated);border:2px solid var(--border-strong);border-radius:.5rem;font-size:.8rem;color:var(--text-primary);font-weight:600}.reports-note{margin-top:.4rem;font-size:.78rem;color:var(--text-muted)}.reports-checked-values .reports-row{font-size:.78rem}.reports-row-button{width:100%;background:none;border:none;border-bottom:1px solid var(--border);text-align:left;color:inherit;font:inherit;cursor:pointer;border-radius:0;align-items:center}.reports-checked-values .reports-row-button{font-size:.78rem}.reports-row-button:hover,.reports-row-button:focus-visible{text-decoration:underline}.reports-row-button.reports-row-selected{box-shadow:inset 3px 0 0 var(--text-primary);padding-left:.5rem;font-weight:600}.reports-row-bad{color:var(--text-primary);font-weight:700;font-size:.78rem}.reports-row-bad:before{content:"✕ "}.reports-detail .reports-case-steps{display:flex;flex-wrap:wrap;gap:.35rem;margin:.25rem 0 .5rem}.reports-legend{margin-bottom:.5rem;padding:.5rem .75rem;background:var(--bg-elevated);border:1px solid var(--border);border-left:4px solid var(--text-muted);border-radius:.5rem;font-size:.8rem;color:var(--text-primary)}.reports-legend{display:flex;flex-wrap:wrap;gap:.25rem 1rem;align-items:center}.reports-legend-chip{display:inline-flex;align-items:center;gap:.4rem}.reports-sw{width:11px;height:11px;border-radius:3px;display:inline-block;flex:none}.reports-sw-v{background:#ecfdf3;border:2px solid #15803d}.reports-sw-a{border:2px dashed #9a9a9a}.reports-gloss-swatch{color:var(--text-muted);border-bottom:1px dotted var(--text-muted)}.reports-gloss-switch{display:inline-flex;align-items:center;gap:.6rem;margin:0 0 .5rem;font-size:.82rem;font-weight:600;cursor:pointer;-webkit-user-select:none;user-select:none}.reports-gloss-switch input{position:absolute;opacity:0;width:1px;height:1px}.reports-gloss-track{width:34px;height:18px;border-radius:999px;background:var(--border);position:relative;flex:none;transition:background .15s ease}.reports-gloss-thumb{position:absolute;top:2px;left:2px;width:14px;height:14px;border-radius:50%;background:var(--bg-elevated);box-shadow:var(--elevation-1);transition:transform .15s ease}.reports-gloss-switch input:checked+.reports-gloss-track{background:var(--text-primary)}.reports-gloss-switch input:checked+.reports-gloss-track .reports-gloss-thumb{transform:translate(16px)}.reports-gloss-switch input:focus-visible+.reports-gloss-track{outline:2px solid var(--text-primary);outline-offset:2px}.reports-iframe{width:100%;height:70vh;min-height:420px;border:1px solid var(--border);border-radius:.75rem;background:#fff}.reports-summary-chip{display:none}@media(max-width:480px){.reports-grid{grid-template-columns:1fr}.reports-summary-chip{display:flex;justify-content:space-between;align-items:center;gap:.75rem;background:var(--bg-elevated);border:1px solid var(--border);border-radius:.75rem;padding:.5rem .75rem;font-size:.8rem;margin-bottom:.75rem}.reports-side{display:none}.reports-side.reports-side-open{display:block}}.mcp-endpoint{font-family:SF Mono,Monaco,monospace;font-size:.85rem;padding:.5rem .75rem;background:var(--bg-elevated);border:1px solid var(--border);border-radius:.375rem;margin-bottom:.75rem;word-break:break-all}.mcp-tabs{display:flex;gap:.25rem;margin-bottom:.75rem;flex-wrap:wrap}.mcp-tab{padding:.375rem .75rem;font-size:.75rem;font-weight:500;font-family:inherit;background:transparent;color:var(--text-secondary);border:1px solid var(--border);border-radius:.375rem;cursor:pointer}.mcp-tab.active{font-weight:600;background:var(--accent-subtle);color:var(--accent);border-color:var(--accent)}.mcp-snippet{font-family:SF Mono,Monaco,monospace;font-size:.78rem;line-height:1.6;padding:.75rem;background:var(--bg-elevated);border:1px solid var(--border);border-radius:.375rem;overflow:auto;white-space:pre-wrap;margin:0 0 .75rem}.setup-card{border:2px solid var(--accent);border-radius:.75rem;padding:1.5rem 1.75rem}.setup-intro{font-size:.88rem;color:var(--text-secondary);line-height:1.6;max-width:40rem;margin-bottom:1.5rem}.flow-step{border-top:1px solid var(--border);padding:1.125rem 0}.flow-step:first-of-type{border-top:none;padding-top:0}.flow-step-head{display:flex;align-items:flex-start;gap:.75rem}.flow-step-marker{width:1.625rem;height:1.625rem;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:.75rem;font-weight:700;flex-shrink:0;margin-top:.05rem}.flow-step-marker.flow-open{border:2px solid var(--accent);color:var(--accent);background:var(--bg-main)}.flow-step-marker.flow-todo{border:2px solid var(--border);color:var(--text-tertiary);background:var(--bg-main)}.flow-step-marker.flow-done{background:var(--neutral);color:var(--bg-elevated);border:2px solid var(--neutral);font-size:.85rem}.flow-step-title{font-size:.95rem;font-weight:700;color:var(--text-primary);margin-top:.1rem}.flow-step-title.flow-todo-title{font-weight:500;color:var(--text-tertiary)}.flow-step-open-btn{background:none;border:0;padding:0;font:inherit;text-align:left;cursor:pointer}.flow-step-open-btn:hover{color:var(--text-primary);text-decoration:underline;text-underline-offset:3px}.flow-step-title.flow-done-title{font-weight:500;color:var(--text-secondary)}.flow-step-title.flow-done-title a{color:var(--text-secondary)}.flow-step-title.flow-done-title a:hover{color:var(--accent)}.flow-step-body{margin:.875rem 0 0 2.375rem;max-width:36rem}.flow-step-body p{font-size:.85rem;color:var(--text-secondary);line-height:1.6;margin-bottom:.75rem}.flow-step-body p:last-child{margin-bottom:0}.bound-list{list-style:none;margin:0 0 .875rem;padding:0;display:flex;flex-direction:column;gap:.375rem}.bound-list li{font-size:.83rem;color:var(--text-secondary);padding-left:1.1rem;position:relative;line-height:1.5}.bound-list li:before{content:"–";position:absolute;left:0;color:var(--text-muted)}.cta-helper{font-size:.76rem;color:var(--text-tertiary);margin-top:.5rem}.managed-note{font-size:.78rem;color:var(--text-tertiary);margin-top:.75rem}.quote-box{display:flex;align-items:center;justify-content:space-between;gap:1rem;flex-wrap:wrap}.quote-text{font-size:.95rem;font-weight:600;font-style:italic;color:var(--text-primary)}@media(max-width:768px){.setup-card{padding:1.25rem}.flow-step-body{margin-left:0;margin-top:.75rem}.quote-box{flex-direction:column;align-items:stretch}}.human-only-note{margin:.75rem 0 1rem;padding:.6rem .8rem;border-left:3px solid var(--text-primary);background:var(--bg-elevated);font-size:.85rem;line-height:1.45;color:var(--text-secondary)}.human-only-note strong{color:var(--text-primary)}.approval-headline{font-size:1.05rem;font-weight:600;color:var(--text-primary);margin-bottom:.6rem}.preview-box{background:var(--bg-main);border:1px solid var(--border);border-left:3px solid var(--accent);border-radius:.5rem;padding:.75rem .875rem;margin-bottom:.75rem;font-size:.85rem}.preview-box h4{font-size:.72rem;font-weight:600;text-transform:uppercase;letter-spacing:.04em;color:var(--text-tertiary);margin-bottom:.3rem}.preview-box-loading{color:var(--text-tertiary);font-size:.82rem}.preview-box-unavailable,.preview-box-not_found{border-left-color:var(--text-muted)}.preview-box-stale{border:2px solid var(--check-failed);border-left-width:3px;background:var(--check-failed-subtle)}.preview-box-stale h5{color:var(--check-failed);font-weight:700}.preview-note{font-size:.78rem;color:var(--text-tertiary);margin-top:.4rem;line-height:1.45}.preview-stale{margin-top:.6rem;padding-top:.6rem;border-top:1px solid var(--border)}.preview-stale h5{font-size:.85rem;font-weight:600;margin-bottom:.3rem}.limit-checks{background:var(--bg-main);border:1px solid var(--border);border-radius:.5rem;padding:.75rem .875rem;margin-bottom:.75rem}.limit-checks h4{font-size:.72rem;font-weight:600;text-transform:uppercase;letter-spacing:.04em;color:var(--text-tertiary);margin-bottom:.35rem}.limit-check-list{list-style:none;margin:0;padding:0;font-size:.85rem;display:flex;flex-direction:column;gap:.2rem}.limit-check-list li{display:flex;gap:.45rem}.limit-check-icon{font-weight:700;flex-shrink:0}.limit-check-list li.ok .limit-check-icon{color:var(--text-primary)}.limit-check-list li.bad{color:var(--check-failed);font-weight:700}.limit-check-list li.bad .limit-check-icon{color:var(--check-failed)}.outcome-box{border:2px solid var(--border-strong);background:var(--bg-elevated);border-radius:.5rem;padding:.75rem .875rem;margin:.5rem 0 .75rem}.outcome-box h4{font-size:.85rem;font-weight:600;color:var(--text-primary);margin-bottom:.3rem}.outcome-note{font-size:.83rem;color:var(--text-secondary);line-height:1.45;margin:0}.mandate-intent{margin-bottom:.75rem;font-size:.85rem}.mandate-intent dl{display:grid;grid-template-columns:max-content 1fr;gap:.35rem .75rem;margin:0 0 .5rem}.mandate-intent dt{color:var(--text-tertiary);white-space:nowrap;align-self:start}.mandate-intent dd{margin:0}.src-tag{font-size:.65rem;font-weight:600;letter-spacing:.04em;text-transform:uppercase;border-radius:.25rem;padding:.05rem .3rem;margin-left:.35rem}.src-tag-local{color:var(--text-muted);border:1px solid var(--border)}.src-tag-sealed{color:var(--prov-sealed);border:1px solid var(--prov-sealed);font-weight:700}.src-tag-system{color:var(--prov-system);border:1px solid var(--prov-system)}.src-tag-value.src-tag-sealed-cell{font-weight:600;color:var(--text-primary)}.src-tag-value.src-tag-system-cell{color:var(--prov-system)}.id-raw{font:.78rem ui-monospace,Menlo,monospace;color:var(--text-muted)}.creation-context{color:var(--text-tertiary);font-size:.82rem}.creation-own-section{margin-top:.75rem;padding-top:.6rem;border-top:1px solid var(--border)}.creation-own-section h5{font-size:.8rem;font-weight:600;margin-bottom:.3rem}.preview-table{width:100%;border-collapse:collapse;font-size:.85rem;margin:.3rem 0}.preview-table th{text-align:left;font-size:.68rem;letter-spacing:.04em;text-transform:uppercase;color:var(--text-tertiary);font-weight:600;border-bottom:1px solid var(--border);padding:.3rem .45rem}.preview-table td{padding:.35rem .45rem;border-bottom:1px solid var(--accent-subtle);vertical-align:top}.creation-legend{display:flex;gap:1.1rem;flex-wrap:wrap;font-size:.72rem;color:var(--text-tertiary);margin:.6rem 0 0}.creation-legend-dot{display:inline-block;width:.5rem;height:.5rem;border-radius:.12rem;margin-right:.3rem;vertical-align:1px}.creation-legend-dot-sealed{background:var(--text-primary)}.creation-legend-dot-system{background:var(--prov-system)}.intent-text{font-style:italic;color:var(--text-secondary);margin:0}.intent-text.intent-clamped{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.intent-toggle{margin-top:.3rem}.preview-box-ai{border-left-color:var(--prov-ai)}.preview-box-sys{border-left-color:var(--prov-system)}.preview-box-unreachable{border-left-color:var(--text-muted)}.src-tag-ai{color:var(--prov-ai);border:1px solid var(--prov-ai)}.au10-req-meta{font-size:.78rem;color:var(--text-tertiary);margin:.1rem 0 .4rem}.au10-req-meta b{color:var(--text-primary);font-weight:600}.au10-req-quote{font-style:italic;color:var(--text-secondary);margin:.1rem 0 .25rem;white-space:pre-wrap}.au10-req-attrib{font-size:.74rem;color:var(--text-tertiary)}.au10-req-state{color:var(--text-tertiary);font-size:.85rem;margin:0}.au10-chain{margin-top:.55rem;padding-top:.5rem;border-top:1px solid var(--border)}.au10-chain summary{cursor:pointer;color:var(--prov-system);font-size:.78rem}.au10-chain-item{margin-top:.4rem;font-size:.78rem}.au10-hist-list{list-style:none;margin:.3rem 0 0;padding:0;display:flex;flex-direction:column;gap:.55rem}.au10-hist-item{padding-top:.5rem;border-top:1px solid var(--border)}.au10-hist-item:first-child{padding-top:0;border-top:none}.au10-hist-head{display:flex;justify-content:space-between;gap:.5rem;font-size:.72rem;color:var(--text-tertiary);text-transform:uppercase;letter-spacing:.02em}.au10-hist-title{font-size:.85rem;font-weight:600;margin:.15rem 0 .1rem}.au10-hist-body{font-style:italic;color:var(--text-secondary);font-size:.82rem;margin:0 0 .2rem}.au10-hist-attrib{font-size:.74rem;color:var(--text-tertiary)}.au10-hist-state{color:var(--text-tertiary);font-size:.85rem;margin:0}.au10-dot{display:inline-block;width:.5rem;height:.5rem;border-radius:.12rem;margin-right:.3rem;vertical-align:1px}.au10-dot-ai{background:var(--prov-ai)}.au10-dot-sys{background:var(--prov-system)}.ticket-done-box{background:var(--bg-elevated);border:1px solid var(--border);border-left:3px solid var(--prov-sealed);border-radius:.5rem;padding:.75rem .875rem;margin-bottom:.75rem;font-size:.85rem}.ticket-done-box h4{font-size:.72rem;font-weight:600;text-transform:uppercase;letter-spacing:.04em;color:var(--text-tertiary);margin-bottom:.3rem}.ticket-done-loading{border-color:var(--border);color:var(--text-tertiary);font-size:.82rem}.ticket-done-off-device,.ticket-done-box[data-bound=none]{border-color:var(--border);background:var(--bg-main)}.ticket-done-mismatch{border:2px solid var(--text-primary);background:var(--bg-elevated)}.ticket-done-unchecked{border-color:var(--border);background:var(--bg-main)}.ticket-done-note{font-size:.78rem;color:var(--text-tertiary);margin:.4rem 0 0;line-height:1.45}.ticket-done-note-ok{color:var(--text-primary);font-weight:600}.ticket-done-note-bad{color:var(--text-primary);font-weight:700}.ticket-done-note-neutral{color:var(--text-tertiary)}.ticket-done-fields{display:grid;grid-template-columns:max-content 1fr;gap:.3rem .75rem;margin:.4rem 0 0}.ticket-done-field-row{display:contents}.ticket-done-field-row dt{color:var(--text-tertiary);white-space:nowrap;align-self:start}.ticket-done-field-row dd{margin:0;word-break:break-word}.ticket-box{background:var(--bg-elevated);border:1px solid var(--border);border-left:3px solid var(--prov-sealed);border-radius:.5rem;padding:.75rem .875rem;margin-bottom:.75rem;font-size:.85rem}.ticket-box h4{font-size:.72rem;font-weight:600;text-transform:uppercase;letter-spacing:.04em;color:var(--text-tertiary);margin-bottom:.3rem}.ticket-shown-off-device,.ticket-shown-unchecked{border-color:var(--border);background:var(--bg-main)}.ticket-shown-mismatch{border:2px solid var(--text-primary);background:var(--bg-elevated)}.ticket-sub-head{font-size:.65rem;font-weight:700;text-transform:uppercase;letter-spacing:.03em;color:var(--text-tertiary);margin:.65rem 0 .3rem}.ticket-sub-head:first-of-type{margin-top:0}.src-tag-danger{color:var(--text-primary);border:2px solid var(--text-primary);font-weight:700}.src-tag-danger:before{content:"✕ "}.msg-error{color:var(--text-primary);font-weight:600}.msg-error:before{content:"✕ "}.msg-ok{color:var(--text-primary)}.msg-ok:before{content:"✓ "}.msg-attention{color:var(--text-primary)}.msg-attention:before{content:"! ";font-weight:700}.note-attention{background:var(--bg-elevated);color:var(--text-primary);border:1px dashed var(--border-strong);border-radius:var(--radius-sm)}.note-stopped{background:var(--bg-elevated);color:var(--text-primary);border:2px solid var(--border-strong);border-radius:var(--radius-sm)}.btn-outline-strong{background:transparent;color:var(--text-primary);border:2px solid var(--btn-outline-border-strong)}.btn-outline-strong:hover:not(:disabled){background:var(--accent-subtle)}.pill-count{display:inline-flex;align-items:center;justify-content:center;min-width:1.15rem;height:1.15rem;padding:0 .35rem;border-radius:var(--radius-pill);background:var(--neutral);color:var(--bg-elevated);font-size:var(--text-micro);font-weight:700;line-height:1}.obj-line{display:flex;align-items:center;gap:.4rem;font-size:var(--text-caption);color:var(--text-muted);white-space:nowrap;overflow:hidden;min-width:0}.obj-line svg{width:1rem;height:1rem;flex:none;color:var(--text-primary)}.obj-line b{color:var(--text-primary);font-weight:700;overflow:hidden;text-overflow:ellipsis}.obj-line .obj-line-sp{flex:1}.obj-due{font-size:var(--text-caption);font-weight:600;color:var(--text-primary);margin-top:.2rem}.appr-item{display:flex;flex-direction:column;background:var(--bg-elevated);border:1px solid var(--border-strong);border-left:6px solid var(--neutral);border-radius:var(--radius-md);margin-bottom:var(--space-2)}.appr-item-head{display:flex;align-items:center;width:100%;background:none;border:none;text-align:left;font:inherit;color:inherit;cursor:pointer;padding:0}.appr-item-head:focus-visible{outline:2px solid var(--text-primary);outline-offset:2px}.appr-item:hover{border-color:var(--text-primary);border-left-color:var(--neutral)}.appr-item-main{flex:1;min-width:0;padding:var(--space-3) var(--space-4)}.appr-item-sum{font-weight:700;color:var(--text-primary)}.appr-item-who{font-size:var(--text-caption);margin-top:.2rem;border-left:2px dashed var(--text-primary);padding-left:.5rem}.appr-item-chev{padding:0 var(--space-4);font-size:1.2rem;color:var(--text-muted)}.appr-item-body{padding:0 var(--space-5) var(--space-4) var(--space-4)}.appr-item.is-open{border:2px solid var(--text-primary);border-left:6px solid var(--neutral);box-shadow:var(--elevation-2);margin:var(--space-3) 0}.appr-item.is-open .appr-item-sum{font-size:var(--text-lead)}.appr-item.is-open .appr-item-chev{transform:rotate(90deg);color:var(--text-primary)}.appr-item-body .card{border:none;box-shadow:none;padding:0;margin:0;background:transparent}.mandate-obj{position:relative;background:var(--bg-elevated);border:1px solid var(--border);border-left:6px solid var(--text-primary);border-radius:var(--radius-lg);padding:var(--space-3) var(--space-4);margin-bottom:var(--space-2)}.mandate-obj-title{font-weight:700;color:var(--text-primary);margin-top:.15rem}.usage{display:flex;align-items:center;gap:var(--space-2);font-size:var(--text-caption);margin-top:var(--space-2);white-space:nowrap}.usage-bar{flex:1;min-width:3rem;height:.35rem;border-radius:var(--radius-pill);background:var(--neutral-subtle);border:1px solid var(--border);overflow:hidden}.usage-bar>i{display:block;height:100%;background:var(--text-primary)}.usage.is-near b{font-weight:800}.ticket-obj{display:flex;background:var(--bg-elevated);border:1px solid var(--border-strong);border-radius:var(--radius-md);margin-bottom:var(--space-2)}.ticket-obj.is-new{border-color:var(--text-primary)}.ticket-obj-main{flex:1;min-width:0;padding:var(--space-3) var(--space-4)}.ticket-obj-what{font-weight:700;font-size:var(--text-body-sm);color:var(--text-primary)}.ticket-obj-stub{flex:0 0 6rem;border-left:2px dashed var(--border-strong);display:flex;flex-direction:column;justify-content:center;align-items:flex-end;gap:.1rem;padding:var(--space-2) var(--space-3)}.ticket-obj-no{font-family:var(--font-mono);font-size:var(--text-caption);font-weight:700;letter-spacing:.03em}.ticket-obj-time{font-size:var(--text-micro);color:var(--text-muted)}.seen-dot{flex:none;width:.55rem;height:.55rem;border-radius:var(--radius-circle);border:1.5px solid var(--text-primary)}.seen-dot.is-new{background:var(--text-primary)}.auto-grp{background:var(--bg-elevated);border:1px solid var(--border-strong);border-radius:var(--radius-md);margin-bottom:var(--space-2)}.auto-grp.is-seen{border-color:var(--border)}.auto-grp>summary{list-style:none;display:flex;gap:var(--space-3);align-items:flex-start;padding:var(--space-3) var(--space-4);cursor:pointer}.auto-grp>summary::-webkit-details-marker{display:none}.auto-grp>summary .seen-dot{margin-top:.35rem}.auto-grp-txt{display:flex;flex-direction:column;min-width:0;font-size:var(--text-body-sm)}.auto-grp-txt>b{color:var(--text-primary)}.auto-grp.is-seen .auto-grp-txt>b{font-weight:600}.auto-grp-list{border-top:1px dashed var(--border-strong);padding:var(--space-2) var(--space-4) var(--space-3)}.auto-grp-row{display:flex;gap:var(--space-2);align-items:baseline;font-size:var(--text-caption);padding:.2rem 0}.auto-grp-row .seen-dot{width:.45rem;height:.45rem}.auto-grp-row .t{margin-left:auto;color:var(--text-muted);white-space:nowrap;font-family:var(--font-mono);font-size:var(--text-micro)}.core-cols{display:grid;grid-template-columns:1.35fr 1.1fr .85fr;gap:var(--space-5);margin-bottom:var(--space-6);align-items:start}.core-col-h{display:flex;align-items:baseline;gap:var(--space-2);margin-bottom:var(--space-3)}.core-col-h h2{font-size:var(--text-body);font-weight:700;margin:0}.core-col-h.is-main h2{font-size:var(--text-lead)}.core-col-h .meta{margin-left:auto;font-size:var(--text-caption);color:var(--text-muted)}.core-col-empty{font-size:var(--text-body-sm);color:var(--text-muted);padding:var(--space-3) 0}.col-btn{display:block;width:100%;text-align:center;margin-top:var(--space-2);padding:.45rem .8rem;border:1px solid var(--text-primary);border-radius:var(--radius-md);font-size:var(--text-body-sm);font-weight:600;color:var(--text-primary);background:var(--bg-elevated);text-decoration:none;cursor:pointer;font-family:inherit}.col-btn:hover{background:var(--accent-subtle);text-decoration:none}.core-quiet-line{font-size:var(--text-caption);color:var(--text-muted);margin-top:var(--space-3);padding-top:var(--space-2);border-top:1px solid var(--border)}.core-quiet-line a{color:var(--text-primary);text-decoration:underline;text-underline-offset:3px}@media(max-width:1100px){.core-cols{grid-template-columns:1fr}}.ftabs{display:flex;gap:var(--space-2);flex-wrap:wrap;align-items:center;margin:var(--space-4) 0 var(--space-3);padding-bottom:var(--space-3);border-bottom:1px solid var(--border)}.ftab{display:inline-flex;align-items:center;gap:.4rem;border:1px solid var(--border);background:transparent;color:var(--text-primary);border-radius:var(--radius-pill);padding:.3rem .8rem;font-size:var(--text-body-sm);font-family:inherit;cursor:pointer}.ftab[aria-selected=true]{border:2px solid var(--text-primary);font-weight:700}.ftab .n{font-size:var(--text-micro);color:var(--text-muted)}.sidebar-core .sidebar-item{font-weight:600}.sidebar-group-label{font-size:.62rem;font-weight:700;letter-spacing:.09em;text-transform:uppercase;color:var(--text-muted);padding:var(--space-3) var(--space-3) var(--space-1)}.sidebar-divider{height:1px;background:var(--border);margin:var(--space-3) var(--space-3)}.sidebar-setup .sidebar-item{color:var(--text-muted);font-size:var(--text-caption)}.nav-ic{display:inline-flex;align-items:center;justify-content:center;width:1.1rem;height:1.1rem;flex:none}.nav-ic-approval{width:.35rem;height:.9rem;background:var(--text-primary);border-radius:2px}.nav-ic-mandate{width:.7rem;height:.9rem;border:1.5px solid var(--text-primary);border-left-width:4px;border-radius:2px}.nav-ic-ticket{width:.95rem;height:.6rem;border:1.5px solid var(--text-primary);border-right-style:dashed;border-radius:2px}.nav-ic-blocked{position:relative;width:.85rem;height:.85rem;border:1.5px solid var(--text-primary);border-radius:var(--radius-circle)}.nav-ic-blocked:after{content:"";position:absolute;left:50%;top:-1px;bottom:-1px;width:1.5px;background:var(--text-primary);transform:translate(-50%) rotate(45deg)}.ticket-obj-head{display:block;width:100%;background:none;border:none;padding:0;text-align:left;font:inherit;color:inherit;cursor:pointer}.ticket-obj-head:focus-visible{outline:2px solid var(--text-primary);outline-offset:2px}.ticket-obj-head .receipt-head{margin-top:.15rem}.ticket-obj-card.is-open{border:2px solid var(--text-primary);box-shadow:var(--elevation-2)}.ticket-obj-card .ticket-obj-stub{flex-basis:7rem}.ticket-obj-sig{font-size:var(--text-micro);font-weight:700}.receipt-when{font-size:var(--text-caption);color:var(--text-muted);margin:var(--space-2) 0}.appr-item-link{flex-direction:row;align-items:center;text-decoration:none;color:inherit}.appr-item-link:hover{text-decoration:none}.attention-quiet{box-shadow:none}.attention-quiet .card-title{font-size:var(--text-body-sm);color:var(--text-muted);font-weight:600}.mandate-card{border-left:6px solid var(--text-primary);padding:0}.mandate-card .id-body{padding:var(--space-3) var(--space-4)}.mandate-card .obj-line{margin-bottom:.15rem}.card-in-row{border:none;box-shadow:none;padding:0;background:transparent;margin:0}.card-in-row .id-body{padding:0}.approval-resp{font-size:var(--text-caption);color:var(--text-muted);margin:var(--space-3) 0 var(--space-2)}.creation-legend-fold{margin:.4rem 0 0}.creation-legend-fold>summary{list-style:none;display:inline-flex;align-items:center;justify-content:center;width:1.1rem;height:1.1rem;border:1px solid var(--border-strong);border-radius:var(--radius-circle);font-size:var(--text-micro);font-weight:700;color:var(--text-muted);cursor:pointer}.creation-legend-fold>summary::-webkit-details-marker{display:none}.creation-legend-fold[open]>summary{color:var(--text-primary);border-color:var(--text-primary)}.card-in-row .approval-headline{font-size:var(--text-caption);font-weight:400;color:var(--text-muted);margin-bottom:var(--space-2)}.approval-summary{font-size:var(--text-lead);font-weight:700;color:var(--text-primary);margin-bottom:.15rem}.card-in-row .approval-summary{display:none}.blocked-card{padding:0}.blocked-card .id-body{padding:var(--space-3) var(--space-4)}.blocked-card .obj-line{margin-bottom:.2rem}
@@ -14,8 +14,8 @@
14
14
  <meta name="apple-mobile-web-app-title" content="Suveren" />
15
15
  <meta name="theme-color" content="#111111" />
16
16
  <title>Suveren</title>
17
- <script type="module" crossorigin src="/assets/index-C2BnlNib.js"></script>
18
- <link rel="stylesheet" crossorigin href="/assets/index-DPgewsLG.css">
17
+ <script type="module" crossorigin src="/assets/index-B7qy0B9J.js"></script>
18
+ <link rel="stylesheet" crossorigin href="/assets/index-DyZY5sLI.css">
19
19
  </head>
20
20
  <body>
21
21
  <div id="root"></div>
@@ -27,6 +27,8 @@ Returns: `Client`
27
27
  * **webSocket** `WebSocketOptions` (optional) - WebSocket-specific configuration options.
28
28
  * **maxFragments** `number` (optional) - Default: `131072` - Maximum number of fragments in a message. Set to 0 to disable the limit.
29
29
  * **maxPayloadSize** `number` (optional) - Default: `134217728` (128 MB) - Maximum allowed payload size in bytes for WebSocket messages. Applied to uncompressed messages, compressed frame payloads, and decompressed (permessage-deflate) messages. Set to 0 to disable the limit.
30
+ * **eventSource** `EventSourceOptions` (optional) - EventSource-specific configuration options.
31
+ * **maxEventSize** `number` (optional) - The maximum total bytes of data and metadata field values retained for a pending EventSource event. Each unfinished line is separately limited to this value plus seven syntax bytes. The number of `data:` lines per event and input chunks buffered for an unfinished line are each limited to `min(131072, max(1024, floor(maxEventSize / 128)))` to bound object overhead. Set to `0` to disable these limits. Default: `buffer.kStringMaxLength`.
30
32
  * **pipelining** `number | null` (optional) - Default: `1` - The amount of concurrent requests to be sent over the single TCP/TLS connection according to [RFC7230](https://tools.ietf.org/html/rfc7230#section-6.3.2). Carefully consider your workload and environment before enabling concurrent requests as pipelining may reduce performance if used incorrectly. Pipelining is sensitive to network stack settings as well as head of line blocking caused by e.g. long running requests. Set to `0` to disable keep-alive connections.
31
33
  * **connect** `ConnectOptions | Function | null` (optional) - Default: `null`.
32
34
  * **strictContentLength** `Boolean` (optional) - Default: `true` - Whether to treat request content length mismatches as errors. If true, an error is thrown when the request content-length header doesn't match the length of the request body. **Security Warning:** Disabling this option can expose your application to HTTP Request Smuggling attacks, where mismatched content-length headers cause servers and proxies to interpret request boundaries differently. This can lead to cache poisoning, credential hijacking, and bypassing security controls. Only disable this in controlled environments where you fully trust the request source.
@@ -41,16 +41,22 @@ const SessionCache = class WeakSessionCache {
41
41
  if (this._sessionCache.has(sessionKey)) {
42
42
  this._sessionCache.delete(sessionKey)
43
43
  } else if (this._sessionCache.size >= this._maxCachedSessions) {
44
+ // Make room for the new session: prefer an entry whose session has
45
+ // already been collected, otherwise evict the oldest one.
46
+ let evicted = false
44
47
  for (const [key, ref] of this._sessionCache) {
45
48
  if (ref.deref() === undefined) {
46
49
  this._sessionCache.delete(key)
47
- return
50
+ evicted = true
51
+ break
48
52
  }
49
53
  }
50
54
 
51
- const oldest = this._sessionCache.keys().next()
52
- if (!oldest.done) {
53
- this._sessionCache.delete(oldest.value)
55
+ if (!evicted) {
56
+ const oldest = this._sessionCache.keys().next()
57
+ if (!oldest.done) {
58
+ this._sessionCache.delete(oldest.value)
59
+ }
54
60
  }
55
61
  }
56
62
 
@@ -5,6 +5,7 @@ module.exports = {
5
5
  kDestroy: Symbol('destroy'),
6
6
  kDispatch: Symbol('dispatch'),
7
7
  kUrl: Symbol('url'),
8
+ kRedirectCacheControl: Symbol('redirect cache control'),
8
9
  kWriting: Symbol('writing'),
9
10
  kResuming: Symbol('resuming'),
10
11
  kQueue: Symbol('queue'),
@@ -22,7 +22,7 @@ function defaultFactory (origin, opts) {
22
22
  }
23
23
 
24
24
  class Agent extends DispatcherBase {
25
- constructor ({ factory = defaultFactory, maxOrigins = Infinity, connect, ...options } = {}) {
25
+ constructor ({ factory = defaultFactory, maxOrigins = Infinity, connect, tls, ...options } = {}) {
26
26
  if (typeof factory !== 'function') {
27
27
  throw new InvalidArgumentError('factory must be a function.')
28
28
  }
@@ -41,7 +41,11 @@ class Agent extends DispatcherBase {
41
41
  connect = { ...connect }
42
42
  }
43
43
 
44
- this[kOptions] = { ...util.deepClone(options), maxOrigins, connect }
44
+ if (tls && typeof tls !== 'function') {
45
+ tls = { ...tls }
46
+ }
47
+
48
+ this[kOptions] = { ...util.deepClone(options), maxOrigins, connect, tls }
45
49
  this[kFactory] = factory
46
50
  this[kClients] = new Map()
47
51
  this[kOrigins] = new Set()
@@ -928,8 +928,6 @@ function connectH1 (client, socket) {
928
928
  }
929
929
 
930
930
  function onHttpSocketError (err) {
931
- assert(err.code !== 'ERR_TLS_CERT_ALTNAME_INVALID')
932
-
933
931
  const parser = this[kParser]
934
932
 
935
933
  // On Mac OS, we get an ECONNRESET even if there is a full body to be forwarded
@@ -293,8 +293,6 @@ function onHttp2SendPing (session) {
293
293
  }
294
294
 
295
295
  function onHttp2SessionError (err) {
296
- assert(err.code !== 'ERR_TLS_CERT_ALTNAME_INVALID')
297
-
298
296
  this[kSocket][kError] = err
299
297
  this[kClient][kOnError](err)
300
298
  }
@@ -436,8 +434,6 @@ function onHttp2SocketClose () {
436
434
  }
437
435
 
438
436
  function onHttp2SocketError (err) {
439
- assert(err.code !== 'ERR_TLS_CERT_ALTNAME_INVALID')
440
-
441
437
  this[kError] = err
442
438
 
443
439
  this[kClient][kOnError](err)
@@ -115,7 +115,8 @@ class Client extends DispatcherBase {
115
115
  initialWindowSize,
116
116
  connectionWindowSize,
117
117
  pingInterval,
118
- webSocket
118
+ webSocket,
119
+ eventSource
119
120
  } = {}) {
120
121
  if (keepAlive !== undefined) {
121
122
  throw new InvalidArgumentError('unsupported keepAlive, use pipelining=0 instead')
@@ -223,7 +224,7 @@ class Client extends DispatcherBase {
223
224
  throw new InvalidArgumentError('pingInterval must be a positive integer, greater or equal to 0')
224
225
  }
225
226
 
226
- super({ webSocket })
227
+ super({ webSocket, eventSource })
227
228
 
228
229
  if (typeof connect !== 'function') {
229
230
  connect = buildConnector({
@@ -1,5 +1,6 @@
1
1
  'use strict'
2
2
 
3
+ const buffer = require('node:buffer')
3
4
  const Dispatcher = require('./dispatcher')
4
5
  const UnwrapHandler = require('../handler/unwrap-handler')
5
6
  const {
@@ -12,6 +13,7 @@ const { kDestroy, kClose, kClosed, kDestroyed, kDispatch } = require('../core/sy
12
13
  const kOnDestroyed = Symbol('onDestroyed')
13
14
  const kOnClosed = Symbol('onClosed')
14
15
  const kWebSocketOptions = Symbol('webSocketOptions')
16
+ const kEventSourceOptions = Symbol('eventSourceOptions')
15
17
 
16
18
  class DispatcherBase extends Dispatcher {
17
19
  /** @type {boolean} */
@@ -32,6 +34,7 @@ class DispatcherBase extends Dispatcher {
32
34
  constructor (opts) {
33
35
  super()
34
36
  this[kWebSocketOptions] = opts?.webSocket ?? {}
37
+ this[kEventSourceOptions] = opts?.eventSource ?? {}
35
38
  }
36
39
 
37
40
  /**
@@ -44,6 +47,15 @@ class DispatcherBase extends Dispatcher {
44
47
  }
45
48
  }
46
49
 
50
+ /**
51
+ * @returns {import('../../types/client').Client.EventSourceOptions}
52
+ */
53
+ get eventSourceOptions () {
54
+ return {
55
+ maxEventSize: this[kEventSourceOptions].maxEventSize ?? buffer.kStringMaxLength
56
+ }
57
+ }
58
+
47
59
  /** @returns {boolean} */
48
60
  get destroyed () {
49
61
  return this[kDestroyed]
@@ -1,6 +1,7 @@
1
1
  'use strict'
2
2
 
3
3
  const util = require('../core/util')
4
+ const { kRedirectCacheControl } = require('../core/symbols')
4
5
  const {
5
6
  parseCacheControlHeader,
6
7
  hasInvalidCacheControlDirective,
@@ -13,6 +14,19 @@ const { parseHttpDate } = require('../util/date.js')
13
14
 
14
15
  function noop () {}
15
16
 
17
+ /**
18
+ * @param {string | URL} a
19
+ * @param {string | URL} b
20
+ * @returns {boolean}
21
+ */
22
+ function sameOrigin (a, b) {
23
+ try {
24
+ return new URL(String(a)).origin === new URL(String(b)).origin
25
+ } catch {
26
+ return String(a) === String(b)
27
+ }
28
+ }
29
+
16
30
  // Status codes that we can use some heuristics on to cache
17
31
  const HEURISTICALLY_CACHEABLE_STATUS_CODES = [
18
32
  200, 203, 204, 206, 300, 301, 308, 404, 405, 410, 414, 501
@@ -151,6 +165,14 @@ class CacheHandler {
151
165
  */
152
166
  #writeStream
153
167
 
168
+ /**
169
+ * The URLs visited while following redirects, shared by reference from the
170
+ * redirect handler through the request context. Carries the suppressed hops'
171
+ * cache-control under {@link kRedirectCacheControl}.
172
+ * @type {URL[] | undefined}
173
+ */
174
+ #history
175
+
154
176
  /**
155
177
  * @param {import('../../types/cache-interceptor.d.ts').default.CacheHandlerOptions} opts
156
178
  * @param {import('../../types/cache-interceptor.d.ts').default.CacheKey} cacheKey
@@ -167,6 +189,9 @@ class CacheHandler {
167
189
  onRequestStart (controller, context) {
168
190
  this.#writeStream?.destroy()
169
191
  this.#writeStream = undefined
192
+ // The redirect handler mutates this shared history as redirects are
193
+ // followed, allowing the cache to identify the response's actual origin.
194
+ this.#history = context?.history
170
195
  this.#handler.onRequestStart?.(controller, context)
171
196
  }
172
197
 
@@ -206,6 +231,29 @@ class CacheHandler {
206
231
  return downstreamOnHeaders()
207
232
  }
208
233
 
234
+ // Never store a response produced by a different origin under the original
235
+ // request's cache key.
236
+ if (this.#history && this.#history.length > 0) {
237
+ const finalUrl = this.#history[this.#history.length - 1]
238
+ if (!sameOrigin(finalUrl.origin, this.#cacheKey.origin)) {
239
+ return downstreamOnHeaders()
240
+ }
241
+ }
242
+
243
+ // Preserve restrictive cache policy from suppressed redirect responses.
244
+ const redirectCacheControl = this.#history?.[kRedirectCacheControl]
245
+ if (redirectCacheControl) {
246
+ for (const hopCacheControl of redirectCacheControl) {
247
+ const hopDirectives = hopCacheControl ? parseCacheControlHeader(hopCacheControl) : {}
248
+ if (
249
+ hopDirectives['no-store'] === true ||
250
+ (this.#cacheType === 'shared' && hopDirectives.private === true)
251
+ ) {
252
+ return downstreamOnHeaders()
253
+ }
254
+ }
255
+ }
256
+
209
257
  const cacheControlHeader = resHeaders['cache-control']
210
258
  const cacheControlDirectives = cacheControlHeader ? parseCacheControlHeader(cacheControlHeader) : {}
211
259
 
@@ -16,6 +16,7 @@ const DEFAULT_MAX_BUFFER_SIZE = 5 * 1024 * 1024
16
16
  * @property {number} bufferedBytes
17
17
  * @property {object | null} pendingTrailers
18
18
  * @property {boolean} done
19
+ * @property {boolean} [pendingStart] onRequestStart deferred until the primary request's context is known
19
20
  */
20
21
 
21
22
  /**
@@ -30,6 +31,20 @@ class DeduplicationHandler {
30
31
  */
31
32
  #primaryHandler
32
33
 
34
+ /**
35
+ * Whether the primary request has started (onRequestStart received). Until
36
+ * then the request context is unknown and cannot be given to waiting handlers.
37
+ * @type {boolean}
38
+ */
39
+ #requestStarted = false
40
+
41
+ /**
42
+ * The primary request context, replayed to waiting handlers so they observe
43
+ * the same redirect history as the primary.
44
+ * @type {any}
45
+ */
46
+ #context = null
47
+
33
48
  /**
34
49
  * @type {WaitingHandler[]}
35
50
  */
@@ -112,20 +127,30 @@ class DeduplicationHandler {
112
127
  const waitingController = waitingHandler.controller
113
128
 
114
129
  try {
115
- handler.onRequestStart?.(waitingController, null)
130
+ if (this.#requestStarted) {
131
+ // The primary request has started, so its context (including the
132
+ // redirect history) is known and can be delivered immediately.
133
+ handler.onRequestStart?.(waitingController, this.#context)
116
134
 
117
- if (waitingController.aborted) {
118
- waitingHandler.done = true
119
- return true
120
- }
135
+ if (waitingController.aborted) {
136
+ waitingHandler.done = true
137
+ return true
138
+ }
121
139
 
122
- if (this.#responseStarted) {
123
- handler.onResponseStart?.(
124
- waitingController,
125
- this.#statusCode,
126
- this.#headers,
127
- this.#statusMessage
128
- )
140
+ if (this.#responseStarted) {
141
+ handler.onResponseStart?.(
142
+ waitingController,
143
+ this.#statusCode,
144
+ this.#headers,
145
+ this.#statusMessage
146
+ )
147
+ }
148
+ } else {
149
+ // The primary request has not started yet. Defer onRequestStart until
150
+ // its context is known, so the waiting handler observes the same
151
+ // redirect history as the primary (a cache handler relies on it to
152
+ // reject cross-origin redirect responses).
153
+ waitingHandler.pendingStart = true
129
154
  }
130
155
  } catch {
131
156
  // Ignore errors from waiting handlers
@@ -146,6 +171,24 @@ class DeduplicationHandler {
146
171
  */
147
172
  onRequestStart (controller, context) {
148
173
  this.#controller = controller
174
+ if (!this.#requestStarted) {
175
+ this.#requestStarted = true
176
+ this.#context = context
177
+ // Deliver the now-known context to handlers that joined before the
178
+ // primary request started.
179
+ for (const waitingHandler of this.#waitingHandlers) {
180
+ if (waitingHandler.pendingStart && !waitingHandler.done && !waitingHandler.controller.aborted) {
181
+ waitingHandler.pendingStart = false
182
+ try {
183
+ waitingHandler.handler.onRequestStart?.(waitingHandler.controller, context)
184
+ } catch {
185
+ // Ignore errors from waiting handlers
186
+ waitingHandler.done = true
187
+ }
188
+ }
189
+ }
190
+ this.#pruneDoneWaitingHandlers()
191
+ }
149
192
  this.#primaryHandler.onRequestStart?.(controller, context)
150
193
  }
151
194
 
@@ -319,7 +362,8 @@ class DeduplicationHandler {
319
362
  bufferedChunks: [],
320
363
  bufferedBytes: 0,
321
364
  pendingTrailers: null,
322
- done: false
365
+ done: false,
366
+ pendingStart: false
323
367
  }
324
368
 
325
369
  const state = {
@@ -1,7 +1,7 @@
1
1
  'use strict'
2
2
 
3
3
  const util = require('../core/util')
4
- const { kBodyUsed } = require('../core/symbols')
4
+ const { kBodyUsed, kRedirectCacheControl } = require('../core/symbols')
5
5
  const assert = require('node:assert')
6
6
  const { InvalidArgumentError } = require('../core/errors')
7
7
  const EE = require('node:events')
@@ -47,6 +47,11 @@ class RedirectHandler {
47
47
  this.maxRedirections = maxRedirections
48
48
  this.handler = handler
49
49
  this.history = []
50
+ // Retain cache-control from suppressed redirect hops for an outer cache.
51
+ Object.defineProperty(this.history, kRedirectCacheControl, {
52
+ value: [],
53
+ enumerable: false
54
+ })
50
55
 
51
56
  if (util.isStream(this.opts.body)) {
52
57
  // TODO (fix): Provide some way for the user to cache the file to e.g. /tmp
@@ -130,6 +135,8 @@ class RedirectHandler {
130
135
  return
131
136
  }
132
137
 
138
+ this.history[kRedirectCacheControl].push(headers['cache-control'])
139
+
133
140
  const { origin, pathname, search } = util.parseURL(new URL(this.location, this.opts.origin && new URL(this.opts.path, this.opts.origin)))
134
141
  const path = search ? `${pathname}${search}` : pathname
135
142
 
@@ -220,9 +220,14 @@ class DecompressHandler extends DecoratorHandler {
220
220
  this.#decompressedSize = decompressedSize
221
221
  }
222
222
 
223
- const result = super.onResponseData(this.#controller, chunk)
224
- if (result === false && !this.#controller.paused) {
225
- this.#controller.pause()
223
+ try {
224
+ const result = super.onResponseData(this.#controller, chunk)
225
+ if (result === false && !this.#controller.paused) {
226
+ this.#controller.pause()
227
+ }
228
+ } catch (err) {
229
+ this.#fail(err)
230
+ return
226
231
  }
227
232
  }
228
233
  } while (this.#drainRequested && !this.#terminated && !this.#controller.paused)
@@ -239,9 +244,14 @@ class DecompressHandler extends DecoratorHandler {
239
244
  return
240
245
  }
241
246
 
242
- this.#terminated = true
243
247
  this.#cleanupDecompressors()
244
- super.onResponseEnd(this.#controller, this.#trailers)
248
+ try {
249
+ super.onResponseEnd(this.#controller, this.#trailers)
250
+ } catch (err) {
251
+ this.#fail(err)
252
+ return
253
+ }
254
+ this.#terminated = true
245
255
  }
246
256
 
247
257
  #onDecompressionEnd () {