Files

205 lines
5.2 KiB
SCSS

// ToastNotification — Sonner headless toast. Each toast renders our own
// <ToastCard/> via toast.custom(), so all card styling below is ours.
$toast-notification-shadow: 0px 2px 6px 0px rgba(25, 33, 71, 0.1);
$toast-notification-width: 500px;
.toast-notification {
// Sonner sizes each toast <li> from --width on the wrapper.
--width: #{$toast-notification-width};
// Sonner sets an inline height at mount and never re-measures, so the card
// can't grow when our panel expands. Force auto so it grows with content.
[data-sonner-toast] {
height: auto !important;
}
&__card {
position: relative;
display: flex;
flex-direction: column;
align-items: stretch;
width: 100%;
min-width: $toast-notification-width;
padding: $pad-smedium $pad-medium;
// Faint accent wash over white, fading out by the midpoint.
background: linear-gradient(
145deg,
rgba(var(--card-accent-rgb), 0.05),
transparent 50%
),
$core-fleet-white;
color: $core-fleet-black;
border: 0;
border-radius: $border-radius-large;
box-shadow: $toast-notification-shadow;
box-sizing: border-box;
font-size: $x-small;
font-family: "Inter", sans-serif;
line-height: $line-height;
gap: 0;
&--open {
gap: $pad-smedium;
}
// Full colour drives the border gradient; the raw RGB channels feed rgba()
// in the background (CSS can't extract channels from a hex custom property).
--card-accent: #{$ui-fleet-black-25};
--card-accent-rgb: 197, 199, 209; // $ui-fleet-black-25
&--success {
--card-accent: #{$ui-success};
--card-accent-rgb: 61, 182, 123; // $ui-success
}
&--error {
--card-accent: #{$ui-error};
--card-accent-rgb: 214, 108, 123; // $ui-error
}
// Gradient border via a masked pseudo-element (border-image ignores radius).
&::before {
content: "";
position: absolute;
inset: 0;
border-radius: inherit;
padding: 1px; // border thickness
background: linear-gradient(
145deg,
rgba(var(--card-accent-rgb), 0.4),
$ui-fleet-black-10
),
$core-fleet-white;
mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
mask-composite: exclude;
pointer-events: none;
}
}
&__header {
display: flex;
// Do not align items center — the icon and action-button rows are each
// one text line tall so they line up with the first line of the
// message, which matters when the message wraps.
justify-content: space-between;
gap: $pad-small;
width: 100%;
}
&__icon-message {
display: flex;
// Top-align so the icon tracks the first line when the message wraps; the
// one-line-tall icon box below keeps a single-line message centered.
align-items: flex-start;
gap: $pad-small;
min-width: 0; // allow the message to shrink / wrap
}
&__icon {
display: inline-flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
width: 16px;
// One line tall with the glyph centered: reads as centered on a single
// line, pins to the first line when the message wraps.
height: calc(#{$x-small} * #{$line-height});
// Fleet's <Icon> wraps the SVG in <div class="icon">.
.icon {
width: 16px;
height: 16px;
display: inline-flex;
}
}
&__message {
margin: 0;
font-size: $x-small;
font-weight: $regular;
line-height: $line-height;
color: $ui-fleet-black-75;
word-break: break-word;
}
&__actions {
display: flex;
align-items: center;
gap: $pad-small;
flex-shrink: 0;
// Match __icon's one-line-tall box so the action buttons visually
// track the first line of text when the message wraps. The subdued
// Button children are 36px tall and intentionally overflow this
// ~21px band — the mismatch is what centers each button on the
// first text line without dragging the whole header down.
height: calc(#{$x-small} * #{$line-height});
}
&__chevron svg {
transition: transform 0.25s ease;
}
&__chevron--open svg {
transform: rotate(180deg);
}
&__panel {
display: flex;
flex-direction: column;
gap: $pad-small;
width: 100%;
border-top: 1px solid $ui-fleet-black-5;
padding-top: $pad-medium;
}
&__panel-header {
display: flex;
align-items: center;
justify-content: space-between;
gap: $pad-small;
}
&__panel-label {
font-size: $x-small;
font-weight: $bold;
color: $core-fleet-black;
}
// Light JSON block — overrides the global dark `pre` to match the ace-fleet
// editor theme.
&__json-block {
margin: 0;
max-height: 200px;
overflow: auto;
box-sizing: border-box;
background-color: $ui-off-white;
color: $core-fleet-black;
border: 1px solid $ui-fleet-black-10;
border-radius: $border-radius;
padding: $pad-smedium;
font-size: $xx-small;
// Token colours darkened from the ace-fleet theme for light-bg contrast.
.key {
color: $ui-fleet-black-75;
}
.string {
color: #2e8b57;
}
.number {
color: #b5651d;
}
.boolean {
color: #4271ae;
}
.null {
color: #6b4290;
}
}
}