/* ============================================================================= components-tier3.css — Tier 3 components (Phase 2) Critical components for ms-ai-architect Playground v3 + universal Aksel patterns. 19. Inherent + residual pair (before/after matrix transition) 20. AI Act compliance-tidslinje (4-milepel timeline + countdown) 21. 3-track entry (Guide/Explore/Expert — carried from Playground v2) 22. FRIA rights-matrix (12 EU Charter rights × impact level) 23. Capability-matrix (license × kapabilitet — available/cost/missing/conditional) 24. Parallel-agent-status panel (multi-worker status grid) 25. ErrorSummary (Aksel/GOV.UK form error pattern) 26. GuidePanel (Aksel friendly inline guidance) ============================================================================= */ /* ============================================================================= 19. INHERENT + RESIDUAL PAIR Used by: ROS (before/after mitigation), DPIA, AI Act mitigations, OKR check-ins Pattern: two cells/scores side-by-side with arrow showing transition. ============================================================================= */ .pair-before-after { display: grid; grid-template-columns: 1fr auto 1fr; gap: var(--space-4); align-items: center; } .pair-before-after__cell { background: var(--color-surface); border: 1px solid var(--color-border-subtle); border-radius: var(--radius-md); padding: var(--space-3) var(--space-4); display: flex; flex-direction: column; gap: 4px; } .pair-before-after__cell-label { font-size: var(--font-size-xs); text-transform: uppercase; letter-spacing: 0.06em; color: var(--color-text-tertiary); font-weight: var(--font-weight-semibold); } .pair-before-after__cell-value { font-size: var(--font-size-2xl); font-weight: var(--font-weight-bold); font-variant-numeric: tabular-nums; letter-spacing: -0.02em; line-height: 1; } .pair-before-after__cell-meta { font-size: var(--font-size-xs); color: var(--color-text-secondary); } .pair-before-after__cell--severity-low { border-left: 4px solid var(--color-severity-low); } .pair-before-after__cell--severity-medium { border-left: 4px solid var(--color-severity-medium); } .pair-before-after__cell--severity-high { border-left: 4px solid var(--color-severity-high); } .pair-before-after__cell--severity-critical { border-left: 4px solid var(--color-severity-critical); } .pair-before-after__cell--severity-extreme { border-left: 4px solid var(--color-severity-extreme); } .pair-before-after__arrow { display: flex; align-items: center; justify-content: center; font-size: var(--font-size-2xl); color: var(--color-text-tertiary); line-height: 1; user-select: none; } .pair-before-after__arrow::before { content: "→"; font-family: var(--font-family-sans); } .pair-before-after__arrow--down::before { content: "↓"; } .pair-before-after__delta { display: inline-flex; align-items: baseline; gap: 4px; font-family: var(--font-family-mono); font-size: var(--font-size-xs); padding: 2px 8px; border-radius: var(--radius-pill); margin-top: 2px; } .pair-before-after__delta--improved { background: var(--color-severity-low-soft); color: var(--color-severity-low-on); } .pair-before-after__delta--worsened { background: var(--color-severity-critical-soft); color: var(--color-severity-critical-on); } @media (max-width: 640px) { .pair-before-after { grid-template-columns: 1fr; } .pair-before-after__arrow { transform: rotate(90deg); } } /* ============================================================================= 20. AI ACT COMPLIANCE-TIDSLINJE Horizontal timeline with 4 fixed EU AI Act milestones (2025-02-02, 2025-08-02, 2026-08-02, 2027-08-02) plus a "today" marker and per-system countdown chips. ============================================================================= */ .aiact-timeline { position: relative; padding: var(--space-8) 0 var(--space-4); margin: var(--space-4) 0; } .aiact-timeline__track { position: relative; height: 4px; background: var(--color-border-subtle); border-radius: var(--radius-pill); margin: 0 12px; } .aiact-timeline__progress { position: absolute; top: 0; bottom: 0; left: 0; background: var(--color-primary-500); border-radius: var(--radius-pill); /* width set inline based on today vs milestone span */ } .aiact-timeline__milestone { position: absolute; top: 50%; transform: translate(-50%, -50%); /* left set inline as percentage based on date span */ } .aiact-timeline__dot { width: 16px; height: 16px; border-radius: 50%; background: var(--color-surface); border: 3px solid var(--color-border-moderate); cursor: pointer; transition: transform var(--duration-fast) var(--ease-default), border-color var(--duration-fast) var(--ease-default); } .aiact-timeline__dot:hover { transform: scale(1.15); } .aiact-timeline__milestone[data-state="passed"] .aiact-timeline__dot { background: var(--color-primary-500); border-color: var(--color-primary-500); } .aiact-timeline__milestone[data-state="active"] .aiact-timeline__dot { background: var(--color-severity-critical); border-color: var(--color-severity-critical); box-shadow: 0 0 0 4px var(--color-severity-critical-soft); } .aiact-timeline__milestone[data-state="upcoming"] .aiact-timeline__dot { background: var(--color-surface); border-color: var(--color-border-strong); } .aiact-timeline__today { position: absolute; top: -6px; bottom: -6px; width: 2px; background: var(--color-text-primary); /* left set inline based on current date */ } .aiact-timeline__today::after { content: "I dag"; position: absolute; top: -22px; left: 50%; transform: translateX(-50%); font-size: 10px; font-family: var(--font-family-mono); font-weight: var(--font-weight-semibold); color: var(--color-text-primary); background: var(--color-bg); padding: 2px 6px; border-radius: var(--radius-sm); white-space: nowrap; } .aiact-timeline__label { position: absolute; top: 22px; left: 50%; transform: translateX(-50%); text-align: center; white-space: nowrap; font-size: 11px; font-family: var(--font-family-mono); color: var(--color-text-secondary); } .aiact-timeline__label-date { font-weight: var(--font-weight-semibold); display: block; } .aiact-timeline__label-name { color: var(--color-text-tertiary); display: block; margin-top: 1px; max-width: 140px; white-space: normal; line-height: 1.2; } .aiact-countdown { display: inline-flex; align-items: center; gap: 6px; padding: 4px 10px; font-size: var(--font-size-xs); font-family: var(--font-family-mono); border-radius: var(--radius-pill); background: var(--color-bg-soft); border: 1px solid var(--color-border-subtle); } .aiact-countdown__days { font-weight: var(--font-weight-bold); font-variant-numeric: tabular-nums; } .aiact-countdown[data-urgency="urgent"] { background: var(--color-severity-critical-soft); color: var(--color-severity-critical-on); border-color: transparent; } .aiact-countdown[data-urgency="soon"] { background: var(--color-severity-medium-soft); color: var(--color-severity-medium-on); border-color: transparent; } .aiact-countdown[data-urgency="distant"] { background: var(--color-severity-low-soft); color: var(--color-severity-low-on); border-color: transparent; } /* ============================================================================= 21. 3-TRACK ENTRY (Guide / Explore / Expert) Carried forward from Playground v2 — the most-validated UX pattern in our fleet. Three large cards as the very first decision the user makes. ============================================================================= */ .tracks { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-5); margin: var(--space-8) 0; } .tracks__card { display: flex; flex-direction: column; gap: var(--space-3); padding: var(--space-6); background: var(--color-surface); border: 1px solid var(--color-border-subtle); border-radius: var(--radius-lg); cursor: pointer; transition: border-color var(--duration-fast) var(--ease-default), transform var(--duration-fast) var(--ease-default), box-shadow var(--duration-fast) var(--ease-default); text-decoration: none; color: inherit; position: relative; overflow: hidden; } .tracks__card::before { content: ""; position: absolute; top: 0; left: 0; right: 0; height: 4px; background: var(--color-border-moderate); transition: background var(--duration-fast) var(--ease-default); } .tracks__card:hover { border-color: var(--color-border-strong); transform: translateY(-2px); box-shadow: var(--shadow-md); } .tracks__card--guided::before { background: var(--color-state-success); } .tracks__card--explore::before { background: var(--color-primary-500); } .tracks__card--expert::before { background: var(--color-text-primary); } .tracks__card-icon { width: 40px; height: 40px; border-radius: var(--radius-md); background: var(--color-bg-soft); display: flex; align-items: center; justify-content: center; color: var(--color-text-secondary); } .tracks__card-title { font-size: var(--font-size-lg); font-weight: var(--font-weight-semibold); margin: 0; } .tracks__card-desc { font-size: var(--font-size-sm); color: var(--color-text-secondary); line-height: var(--line-height-snug); margin: 0; } .tracks__card-meta { margin-top: auto; padding-top: var(--space-3); display: flex; justify-content: space-between; align-items: baseline; font-size: var(--font-size-xs); color: var(--color-text-tertiary); font-family: var(--font-family-mono); } .tracks__card-cta { font-family: var(--font-family-sans); font-weight: var(--font-weight-medium); color: var(--color-text-primary); } @media (max-width: 880px) { .tracks { grid-template-columns: 1fr; } } /* ============================================================================= 22. FRIA RIGHTS-MATRIX 12 EU Charter rights × impact level. Long left labels, compact right cells. Each cell shows checkmark + severity color when right is impacted. ============================================================================= */ .rights-matrix { display: grid; grid-template-columns: 1fr; gap: 1px; background: var(--color-border-subtle); border: 1px solid var(--color-border-subtle); border-radius: var(--radius-md); overflow: hidden; } .rights-matrix__head, .rights-matrix__row { display: grid; grid-template-columns: 1fr repeat(5, 64px); background: var(--color-surface); } .rights-matrix__head { background: var(--color-bg-soft); } .rights-matrix__head-cell, .rights-matrix__name, .rights-matrix__cell { padding: 10px 12px; font-size: var(--font-size-sm); display: flex; align-items: center; } .rights-matrix__head-cell { font-size: var(--font-size-xs); font-weight: var(--font-weight-semibold); text-transform: uppercase; letter-spacing: 0.04em; color: var(--color-text-secondary); justify-content: center; } .rights-matrix__head-cell--name { justify-content: flex-start; } .rights-matrix__name { font-weight: var(--font-weight-medium); color: var(--color-text-primary); } .rights-matrix__name-meta { display: block; font-size: var(--font-size-xs); color: var(--color-text-tertiary); font-weight: var(--font-weight-regular); margin-top: 2px; } .rights-matrix__cell { justify-content: center; font-family: var(--font-family-mono); font-size: var(--font-size-sm); font-weight: var(--font-weight-semibold); font-variant-numeric: tabular-nums; color: var(--color-text-tertiary); border-left: 1px solid var(--color-border-subtle); } .rights-matrix__cell[data-impact="0"]::before { content: "—"; color: var(--color-text-tertiary); } .rights-matrix__cell[data-impact="1"] { background: var(--color-severity-low-soft); color: var(--color-severity-low-on); } .rights-matrix__cell[data-impact="2"] { background: var(--color-severity-medium-soft); color: var(--color-severity-medium-on); } .rights-matrix__cell[data-impact="3"] { background: var(--color-severity-high-soft); color: var(--color-severity-high-on); } .rights-matrix__cell[data-impact="4"] { background: var(--color-severity-critical-soft); color: var(--color-severity-critical-on); } .rights-matrix__cell[data-impact="5"] { background: var(--color-severity-critical); color: var(--color-severity-critical-on); } @media (max-width: 720px) { .rights-matrix__head, .rights-matrix__row { grid-template-columns: 1fr repeat(5, 44px); } .rights-matrix__head-cell, .rights-matrix__cell { padding: 8px 6px; font-size: var(--font-size-xs); } } /* ============================================================================= 23. CAPABILITY-MATRIX Rows = capabilities (e.g. "Generate text via M365 Chat"), columns = licenses (E3, E5, Copilot, etc.). Cells use one of four states with explicit icon + color so meaning never depends solely on color. ============================================================================= */ .capability-matrix { display: grid; gap: 1px; background: var(--color-border-subtle); border: 1px solid var(--color-border-subtle); border-radius: var(--radius-md); overflow: hidden; font-size: var(--font-size-sm); } .capability-matrix__head, .capability-matrix__row { display: grid; background: var(--color-surface); /* grid-template-columns set inline based on license count */ } .capability-matrix__head { background: var(--color-bg-soft); } .capability-matrix__head-cell, .capability-matrix__name, .capability-matrix__cell { padding: 10px 12px; display: flex; align-items: center; gap: 6px; } .capability-matrix__head-cell { font-size: var(--font-size-xs); font-weight: var(--font-weight-semibold); text-transform: uppercase; letter-spacing: 0.04em; color: var(--color-text-secondary); justify-content: center; } .capability-matrix__head-cell--name { justify-content: flex-start; } .capability-matrix__name { font-weight: var(--font-weight-medium); border-right: 1px solid var(--color-border-subtle); } .capability-matrix__cell { justify-content: center; font-family: var(--font-family-mono); font-size: var(--font-size-md); border-left: 1px solid var(--color-border-subtle); } .capability-matrix__cell-icon { font-style: normal; width: 22px; height: 22px; display: inline-flex; align-items: center; justify-content: center; border-radius: 50%; font-size: 13px; font-weight: var(--font-weight-bold); } .capability-matrix__cell[data-status="available"] { background: var(--color-severity-low-soft); } .capability-matrix__cell[data-status="available"] .capability-matrix__cell-icon { background: var(--color-severity-low); color: #fff; } .capability-matrix__cell[data-status="available"] .capability-matrix__cell-icon::before { content: "✓"; } .capability-matrix__cell[data-status="cost"] { background: var(--color-severity-medium-soft); } .capability-matrix__cell[data-status="cost"] .capability-matrix__cell-icon { background: var(--color-severity-medium); color: #fff; } .capability-matrix__cell[data-status="cost"] .capability-matrix__cell-icon::before { content: "kr"; font-size: 10px; } .capability-matrix__cell[data-status="conditional"] { background: var(--color-severity-high-soft); } .capability-matrix__cell[data-status="conditional"] .capability-matrix__cell-icon { background: var(--color-severity-high); color: #fff; } .capability-matrix__cell[data-status="conditional"] .capability-matrix__cell-icon::before { content: "!"; } .capability-matrix__cell[data-status="missing"] { background: var(--color-bg-soft); } .capability-matrix__cell[data-status="missing"] .capability-matrix__cell-icon { background: var(--color-text-tertiary); color: #fff; } .capability-matrix__cell[data-status="missing"] .capability-matrix__cell-icon::before { content: "×"; } .capability-matrix__legend { display: flex; gap: var(--space-4); flex-wrap: wrap; font-size: var(--font-size-xs); margin-top: var(--space-3); color: var(--color-text-secondary); } .capability-matrix__legend-item { display: inline-flex; align-items: center; gap: 6px; } /* ============================================================================= 24. PARALLEL-AGENT-STATUS PANEL Used by ms-ai-architect utredning (4 parallel workers — security-worker, cost-worker, dpia-worker, diagram-worker writing to .work/-files) and ultraplan-local multi-wave execute. Grid of agent cards with state pills, progress bars, and per-agent metrics. ============================================================================= */ .agent-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: var(--space-3); } .agent-card { background: var(--color-surface); border: 1px solid var(--color-border-subtle); border-radius: var(--radius-md); padding: var(--space-4); display: flex; flex-direction: column; gap: var(--space-2); position: relative; } .agent-card__head { display: flex; justify-content: space-between; align-items: flex-start; gap: var(--space-2); } .agent-card__name { font-weight: var(--font-weight-semibold); font-size: var(--font-size-sm); margin: 0; } .agent-card__role { font-family: var(--font-family-mono); font-size: 11px; color: var(--color-text-tertiary); } .agent-card__state { display: inline-flex; align-items: center; gap: 4px; padding: 2px 8px; font-size: 11px; font-weight: var(--font-weight-medium); border-radius: var(--radius-pill); white-space: nowrap; } .agent-card__state[data-state="queued"] { background: var(--color-bg-soft); color: var(--color-text-tertiary); } .agent-card__state[data-state="running"] { background: var(--color-severity-medium-soft); color: var(--color-severity-medium-on); } .agent-card__state[data-state="done"] { background: var(--color-severity-low-soft); color: var(--color-severity-low-on); } .agent-card__state[data-state="failed"] { background: var(--color-state-failed); color: #fff; } .agent-card__state[data-state="blocked"] { background: var(--color-state-blocked); color: #fff; } .agent-card__state-dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; } .agent-card__state[data-state="running"] .agent-card__state-dot { animation: agent-pulse 1.4s var(--ease-default) infinite; } @keyframes agent-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.35; } } .agent-card__progress { height: 4px; background: var(--color-surface-sunken); border-radius: var(--radius-pill); overflow: hidden; } .agent-card__progress-fill { height: 100%; background: var(--color-primary-500); transition: width var(--duration-normal) var(--ease-default); } .agent-card__metrics { display: flex; gap: var(--space-3); font-size: var(--font-size-xs); color: var(--color-text-secondary); } .agent-card__metric { display: flex; gap: 4px; align-items: baseline; } .agent-card__metric-value { font-variant-numeric: tabular-nums; font-weight: var(--font-weight-semibold); color: var(--color-text-primary); } .agent-card__output { font-family: var(--font-family-mono); font-size: 11px; background: var(--color-surface-sunken); padding: 6px 8px; border-radius: var(--radius-sm); max-height: 56px; overflow: hidden; color: var(--color-text-secondary); white-space: pre-wrap; word-break: break-word; } .agent-card__output::after { content: ""; position: absolute; bottom: var(--space-4); left: var(--space-4); right: var(--space-4); height: 18px; background: linear-gradient(to bottom, transparent, var(--color-surface)); pointer-events: none; } /* ============================================================================= 25. ERROR-SUMMARY (Aksel/GOV.UK pattern) Concentrated list of validation errors at top of a form. Each error anchor-links to the offending field. Required for accessible long forms. ============================================================================= */ .error-summary { background: var(--color-surface); border: 1px solid var(--color-severity-critical); border-left-width: 4px; border-radius: var(--radius-md); padding: var(--space-4) var(--space-5); display: flex; flex-direction: column; gap: var(--space-2); } .error-summary__heading { display: flex; align-items: center; gap: 8px; font-size: var(--font-size-md); font-weight: var(--font-weight-semibold); color: var(--color-severity-critical); margin: 0; } [data-theme="dark"] .error-summary__heading { color: #F09095; } .error-summary__heading::before { content: "!"; display: inline-flex; align-items: center; justify-content: center; width: 20px; height: 20px; border-radius: 50%; background: var(--color-severity-critical); color: #fff; font-size: 14px; font-weight: var(--font-weight-bold); flex-shrink: 0; } .error-summary__body { font-size: var(--font-size-sm); color: var(--color-text-primary); line-height: var(--line-height-snug); } .error-summary__list { margin: var(--space-2) 0 0; padding: 0 0 0 var(--space-5); list-style: disc; color: var(--color-text-primary); } .error-summary__item { margin-bottom: 4px; } .error-summary__link { color: var(--color-severity-critical); text-decoration: underline; text-underline-offset: 2px; text-decoration-thickness: 1px; font-weight: var(--font-weight-medium); } .error-summary__link:hover { text-decoration-thickness: 2px; color: var(--color-severity-extreme); } [data-theme="dark"] .error-summary__link { color: #F09095; } [data-theme="dark"] .error-summary__link:hover { color: #FFB7BA; } /* ============================================================================= 26. GUIDE-PANEL (Aksel pattern) Friendly inline guidance with optional illustration and CTA. Used to scaffold first-time users through unfamiliar territory without scolding tone. ============================================================================= */ .guide-panel { display: grid; grid-template-columns: 56px 1fr auto; gap: var(--space-4); align-items: start; background: var(--color-bg-soft); border: 1px solid var(--color-border-subtle); border-radius: var(--radius-lg); padding: var(--space-4) var(--space-5); } .guide-panel--info { background: #EAF3FB; border-color: rgba(9, 105, 218, 0.25); } .guide-panel--success { background: var(--color-severity-low-soft); border-color: rgba(26, 127, 55, 0.3); } .guide-panel--warn { background: var(--color-severity-medium-soft); border-color: rgba(191, 135, 0, 0.3); } [data-theme="dark"] .guide-panel--info { background: #0E2A3F; border-color: rgba(111, 165, 221, 0.3); } .guide-panel__icon { width: 56px; height: 56px; border-radius: var(--radius-md); background: var(--color-surface); border: 1px solid var(--color-border-subtle); display: flex; align-items: center; justify-content: center; color: var(--color-primary-500); } .guide-panel--info .guide-panel__icon { color: var(--color-state-info); } .guide-panel--success .guide-panel__icon { color: var(--color-state-success); } .guide-panel--warn .guide-panel__icon { color: var(--color-severity-medium); } .guide-panel__body { display: flex; flex-direction: column; gap: 4px; min-width: 0; } .guide-panel__title { font-size: var(--font-size-md); font-weight: var(--font-weight-semibold); margin: 0; color: var(--color-text-primary); } .guide-panel__text { font-size: var(--font-size-sm); color: var(--color-text-secondary); line-height: var(--line-height-snug); margin: 0; max-width: var(--measure); } .guide-panel__action { align-self: center; white-space: nowrap; } .guide-panel__dismiss { position: absolute; top: var(--space-2); right: var(--space-2); background: none; border: none; cursor: pointer; width: 28px; height: 28px; border-radius: var(--radius-sm); display: flex; align-items: center; justify-content: center; color: var(--color-text-tertiary); font-family: inherit; } .guide-panel__dismiss:hover { background: rgba(0,0,0,0.06); color: var(--color-text-primary); } @media (max-width: 640px) { .guide-panel { grid-template-columns: 40px 1fr; gap: var(--space-3); } .guide-panel__icon { width: 40px; height: 40px; } .guide-panel__action { grid-column: 1 / -1; align-self: stretch; } } /* ============================================================================= Print rules for Tier 3 ============================================================================= */ @media print { .pair-before-after { page-break-inside: avoid; } .aiact-timeline { page-break-inside: avoid; } .agent-grid { page-break-inside: avoid; } .tracks { display: none; } /* entry choice = screen-only */ .guide-panel__dismiss { display: none; } /* dismiss only meaningful on screen */ .error-summary { background: #FFF !important; border: 1pt solid #000 !important; color: #000 !important; } .error-summary__heading, .error-summary__body, .error-summary__link { color: #000 !important; } }