SyncMadeEasy/force-app/main/default/lwc/shopifyCredentials/shopifyCredentials.css

1304 lines
31 KiB
CSS

:host {
--smepro-green: #5fa832;
--smepro-teal: #3f9a86;
}
:host {
font-family: 'Inter', system-ui, sans-serif;
color: #1c2b23;
display: block;
}
a { color: #2f7d32; text-decoration: none; }
a:hover { color: #1f5a22; text-decoration: underline; }
@keyframes sw-spin { to { transform: rotate(360deg); } }
@keyframes sw-pulse {
0%, 100% { opacity: .35; transform: scale(.8); }
50% { opacity: 1; transform: scale(1.15); }
}
.sw-loading {
display: flex;
align-items: center;
justify-content: center;
position: absolute;
inset: 0;
min-height: 100%;
width: 100%;
padding: 40px 0;
box-sizing: border-box;
background: linear-gradient(180deg, #f4faee 0%, #eaf3fb 100%);
border-radius: 16px;
}
.pageLoading-Gif { width: 30%; margin-top: 2%; }
/* Card */
.sw-card {
border: 1px solid #e6ebe6;
border-radius: 16px;
box-shadow: 0 10px 26px -16px rgba(23,43,32,.28);
/* Allow the Auto Configuration tooltip to extend outside the card. */
overflow: visible;
background: #fff;
}
.sw-card-header {
padding: 22px 26px;
border-bottom: 1px solid #f0f2f0;
display: flex;
align-items: center;
justify-content: space-between;
gap: 16px;
position: relative;
z-index: 1;
}
.sw-title {
margin: 0;
font-size: 19px;
font-weight: 800;
letter-spacing: -.01em;
color: #1c2b23;
}
.sw-subtitle {
margin: 6px 0 0;
font-size: 13px;
color: #6b786f;
max-width: 480px;
}
.sw-header-right {
display: flex;
align-items: center;
gap: 14px;
flex-shrink: 0;
}
.sw-divider {
width: 1px;
height: 26px;
background: #e6ebe6;
}
.sw-auto-label {
font-size: 13px;
font-weight: 600;
color: #37453d;
}
/* Connection pill */
.conn-pill {
display: inline-flex;
align-items: center;
gap: 7px;
font-size: 12px;
font-weight: 600;
padding: 6px 12px;
border-radius: 20px;
white-space: nowrap;
}
.conn-pill_on { background: #eef7e3; color: #4f8a24; }
.conn-pill_off { background: #fdf6e3; color: #8a6d00; }
.conn-dot {
width: 7px;
height: 7px;
border-radius: 50%;
background: currentColor;
display: inline-block;
}
.conn-dot_pulse {
box-shadow: 0 0 0 4px rgba(95,168,50,.18);
animation: sw-pulse 1.6s ease-in-out infinite;
}
/* Sync direction hero */
.sw-hero {
margin: 20px 26px 0;
background: linear-gradient(105deg,#eef7e3 0%,#e6f1fb 100%);
border: 1px solid #dde8ea;
border-radius: 14px;
padding: 18px 26px;
display: flex;
align-items: center;
gap: 20px;
box-shadow: 0 10px 24px -18px rgba(63,138,36,.35), 0 14px 30px -20px rgba(47,143,176,.3);
flex-wrap: wrap;
}
.hero-side {
display: flex;
align-items: center;
gap: 12px;
flex: 1;
min-width: 140px;
}
.hero-side_right { justify-content: flex-end; }
.hero-text_right { text-align: right; }
.hero-icon {
width: 54px;
height: 54px;
border-radius: 11px;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
}
.hero-icon_shopify {
background: transparent;
color: #4f8a24;
box-shadow: none;
}
.hero-icon_sf {
background: transparent;
color: #0176d3;
box-shadow: none;
}
.hero-icon-img {
width: 54px;
height: 54px;
object-fit: contain;
}
.hero-icon_shopify .hero-icon-img {
width: 44px;
height: 44px;
}
.hero-name { font-size: 14px; font-weight: 800; color: #1c2b23; }
.hero-sub { font-size: 12px; color: #7c8a80; }
.hero-mid {
flex: 1.6;
display: flex;
flex-direction: column;
align-items: center;
gap: 6px;
min-width: 220px;
}
.hero-line-row {
display: flex;
align-items: center;
gap: 10px;
width: 100%;
}
.hero-line {
flex: 1;
height: 2px;
border-radius: 2px;
}
.hero-line_left { background: linear-gradient(90deg,#bcd9a6,#5fa832); }
.hero-line_right { background: linear-gradient(90deg,#5fa832,#bcd9a6); }
.hero-mid .conn-pill {
background: #fff;
border: 1px solid #dcefca;
box-shadow: 0 2px 6px rgba(95,168,50,.15);
padding: 6px 14px;
}
.hero-mid .conn-pill_off { border-color: #f0e2ba; }
.hero-note {
font-size: 10.5px;
font-weight: 600;
color: #8a978d;
}
/* Form fields */
.sw-fields {
padding: 24px 26px 8px;
display: flex;
flex-direction: column;
gap: 16px;
}
.field-row {
display: grid;
grid-template-columns: 210px 1fr;
align-items: center;
gap: 16px;
}
.field-row:focus-within {
position: relative;
z-index: 2;
}
.field-label {
display: flex;
align-items: center;
gap: 7px;
}
.field-label label {
font-size: 13.5px;
font-weight: 600;
color: #37453d;
}
.field-input {
width: 100%;
background: #F3F3F3;
color: #747474;
border-radius: 9px;
--slds-c-input-color-background: transparent;
--slds-c-input-color-background-disabled: transparent;
--lwc-colorBackgroundInputDisabled: transparent;
--lwc-colorBackgroundInput: transparent;
--lwc-colorBackgroundButtonDefault: transparent;
}
.field-input .slds-dropdown,
.field-input [class*="slds-listbox"] {
--slds-g-color-neutral-base-95: #ffffff;
--slds-g-color-neutral-base-100: #ffffff;
--lwc-colorBackground: #ffffff;
}
.token-wrap {
position: relative;
display: flex;
align-items: center;
}
.field-input_token {
width: 100%;
}
.token-eye {
position: absolute;
right: 8px;
background: none;
border: none;
padding: 6px;
cursor: pointer;
color: #7c8a80;
display: flex;
z-index: 1;
}
.token-eye:hover { color: #37453d; }
/* .token-eye is normally an absolutely-positioned "show/hide" toggle sitting
inside a position:relative field wrapper (the real access-token field).
Reused here as a plain copy button inside a flex row that has no
position:relative ancestor of its own — so `position:absolute; right:8px`
was escaping all the way up to the modal overlay (position:fixed) and
pinning itself to the viewport's right edge instead of the small box,
making it appear to vanish/shift depending on window size/zoom. Put it
back in normal flex flow for just these two usages. */
.gen-token-store-banner .token-eye,
.gen-token-redirect-row .token-eye {
position: static;
right: auto;
flex-shrink: 0;
}
.field-actions {
display: flex;
align-items: center;
gap: 12px;
justify-content: center;
flex-wrap: wrap;
}
.sw-btn {
display: inline-flex;
align-items: center;
gap: 8px;
border-radius: 9px;
padding: 10px 18px;
font-size: 13px;
font-weight: 700;
cursor: pointer;
font-family: inherit;
border: none;
}
.sw-btn_primary {
background: linear-gradient(120deg,#5fa832,#3f9a86);
color: #fff;
box-shadow: 0 6px 18px -6px rgba(58,150,120,.55), 0 2px 6px rgba(95,168,50,.25);
transition: box-shadow .2s, transform .15s;
}
.sw-btn_primary:hover:not(:disabled) {
box-shadow: 0 8px 22px -4px rgba(58,150,120,.65), 0 3px 8px rgba(95,168,50,.3);
transform: translateY(-1px);
}
.sw-btn_muted {
background: #fff;
color: #a8a8a8;
border: 1px solid #d4d9d4;
box-shadow: 0 2px 6px rgba(0,0,0,.06);
opacity: .65;
cursor: not-allowed;
}
.sw-btn:disabled { cursor: not-allowed; }
/* Auto Configuration summary */
.auto-summary-wrap { padding: 8px 26px 4px; }
.auto-summary-card {
background: linear-gradient(120deg,#f4faee 0%,#eaf3fb 100%);
border: 1px solid #dce8e2;
border-radius: 14px;
padding: 22px 24px;
}
.auto-summary-head {
display: flex;
align-items: center;
gap: 12px;
margin-bottom: 16px;
}
.auto-summary-icon {
width: 40px;
height: 40px;
border-radius: 11px;
/* background: #5fa832; */
background: linear-gradient(120deg, #5fa832, #2f8fb0);
display: flex;
align-items: center;
justify-content: center;
color: #fff;
box-shadow: 0 4px 12px rgba(95,168,50,.3);
flex-shrink: 0;
}
.auto-summary-title {
font-size: 15.5px;
font-weight: 800;
color: #1c2b23;
}
.auto-summary-sub {
font-size: 12.5px;
color: #6b786f;
}
.auto-summary-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 12px;
}
.auto-summary-item {
display: flex;
align-items: center;
gap: 11px;
background: #fff;
border: 1px solid #e4eee0;
border-radius: 11px;
padding: 13px 15px;
}
.auto-summary-item-title {
font-size: 13px;
font-weight: 700;
color: #26332b;
}
.auto-summary-item-sub {
font-size: 12px;
color: #7c8a80;
}
.auto-summary-footnote {
display: flex;
align-items: center;
gap: 8px;
margin-top: 16px;
font-size: 12.5px;
color: #6b786f;
}
.auto-summary-footnote strong { color: #37453d; }
@media (max-width: 560px) {
.auto-summary-grid { grid-template-columns: 1fr; }
}
/* Access scope error */
.scope-error-card {
margin: 8px 26px 0;
background: #fdeaea;
border: 1px solid #f6c9c7;
border-radius: 14px;
padding: 18px 22px;
}
.scope-error-title {
font-size: 14.5px;
font-weight: 800;
color: #a4302b;
margin-bottom: 10px;
}
.scope-error-list {
margin: 0 0 10px;
padding-left: 18px;
}
.scope-error-item {
font-size: 13px;
color: #a4302b;
margin-bottom: 4px;
}
.scope-error-help {
margin: 0;
font-size: 12.5px;
color: #6b786f;
line-height: 1.5;
}
/* Two panels */
.sw-panels {
padding: 20px 26px 8px;
display: grid;
grid-template-columns: 1fr 1fr;
gap: 18px;
}
.panel-card {
background: linear-gradient(120deg,#f4faee 0%,#eaf3fb 100%);
border: 1px solid #e4ebe6;
border-radius: 14px;
padding: 18px 20px;
box-shadow: 0 6px 18px -12px rgba(23,43,32,.22);
}
.panel-card_emails {
display: flex;
flex-direction: column;
}
.panel-head {
display: flex;
align-items: center;
justify-content: space-between;
gap: 8px;
margin-bottom: 14px;
}
.panel-title {
margin: 0;
font-size: 15px;
font-weight: 800;
color: #1c2b23;
line-height: 1.35;
}
.panel-sub {
margin: 5px 0 16px;
font-size: 12.5px;
color: #6b786f;
line-height: 1.5;
}
.obj-count-badge {
font-size: 11.5px;
font-weight: 700;
color: #4f8a24;
background: #e6f3d5;
padding: 3px 10px;
border-radius: 20px;
}
.obj-row {
display: flex;
align-items: center;
justify-content: space-between;
padding: 9px 0;
border-bottom: 1px solid #f0f2f0;
gap: 10px;
}
.obj-row_last { border-bottom: none; }
.obj-left {
display: flex;
align-items: center;
gap: 11px;
}
.obj-icon {
width: 30px;
height: 30px;
flex: 0 0 auto;
border-radius: 8px;
background: #ecf6e3;
display: flex;
align-items: center;
justify-content: center;
color: #4f8a24;
}
.obj-label {
font-size: 13.5px;
font-weight: 600;
color: #37453d;
}
.obj-right {
display: flex;
align-items: center;
gap: 9px;
}
.required-tag {
font-size: 10.5px;
font-weight: 700;
color: #9aa79d;
background: #eef1ee;
padding: 2px 8px;
border-radius: 20px;
}
.locked-toggle {
position: relative;
width: 42px;
height: 24px;
flex: 0 0 auto;
border-radius: 999px;
/* background: #bcd9a6; */
background: linear-gradient(120deg, #5fa832, #2f8fb0);
cursor: not-allowed;
opacity: .7;
}
.locked-knob {
position: absolute;
top: 3px;
left: 21px;
width: 18px;
height: 18px;
border-radius: 50%;
background: #fff;
box-shadow: 0 1px 3px rgba(0,0,0,.25);
}
/* Live toggle switches — plain custom button+knob (not lightning-input
type=toggle, whose SLDS styling hooks didn't reliably take: it flashed
blue on click then settled back to a default grey). Matches the
reference's exact 42x24 pill/knob look and green-on/grey-off colors. */
.obj-toggle-track {
position: relative;
width: 42px;
height: 24px;
flex: 0 0 auto;
border-radius: 999px;
border: none;
padding: 0;
cursor: pointer;
background: rgb(205, 212, 205);
transition: background .2s, box-shadow .2s;
/* Lightning Experience's global stylesheet puts a blue focus ring on
every plain <button> (its default :focus box-shadow/outline). Since
clicking a button also focuses it, that blue ring showed the instant
you clicked — and only went away once focus moved elsewhere (click
outside, or tabbing off), which read as "turns blue, then a few
seconds later goes green." Overriding :focus below removes that. */
outline: none;
-webkit-tap-highlight-color: transparent;
}
.obj-toggle-track:focus,
.obj-toggle-track:focus-visible,
.obj-toggle-track:active {
outline: none;
box-shadow: none;
}
.obj-toggle-track_on {
background: linear-gradient(120deg, #5fa832, #2f8fb0);
box-shadow: 0 0 0 3px rgba(58, 150, 120, .16), 0 4px 10px -2px rgba(58, 150, 120, .5);
}
.obj-toggle-track_on:focus,
.obj-toggle-track_on:focus-visible,
.obj-toggle-track_on:active {
box-shadow: 0 0 0 3px rgba(58,150,120,.16), 0 4px 10px -2px rgba(58,150,120,.5);
}
.obj-toggle-knob {
position: absolute;
top: 3px;
left: 3px;
width: 18px;
height: 18px;
border-radius: 50%;
background: #fff;
transition: left .2s;
box-shadow: 0 1px 3px rgba(0,0,0,.25);
}
.obj-toggle-track_on .obj-toggle-knob {
left: 21px;
}
/* Emails */
.email-row {
display: flex;
align-items: center;
gap: 10px;
padding: 4px 2px;
margin-bottom: 10px;
}
.email-check-icon { flex: 0 0 auto; }
.email-text {
flex: 1;
min-width: 0;
font-size: 13px;
color: #26332b;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.email-input-native {
flex: 1;
min-width: 0;
font: inherit;
font-size: 13px;
color: #26332b;
background: #fff;
border: 1px solid rgb(95, 168, 50);
border-radius: 8px;
padding: 8px 12px;
outline: none;
box-sizing: border-box;
}
.email-icon-btn {
background: none;
border: none;
padding: 4px;
cursor: pointer;
color: #5fa832;
display: flex;
flex: 0 0 auto;
}
.email-icon-btn:hover { color: #3f8f2f; }
.email-icon-btn_danger { color: #c99; }
.email-icon-btn_danger:hover { color: #c23934; }
.add-email-btn {
display: flex;
align-items: center;
justify-content: center;
gap: 7px;
width: 100%;
font: inherit;
font-size: 13px;
font-weight: 700;
padding: 10px 0;
border-radius: 10px;
border: 1.5px dashed #bcd9a6;
background: #f1f8ec;
/* color: #4f8a24; */
color: rgb(47, 107, 74);
cursor: pointer;
}
.add-email-btn_disabled {
border-color: #dcdcdc;
background: #f5f5f5;
color: #a8a8a8;
cursor: not-allowed;
}
.email-hint {
padding-top: 12px;
padding-bottom: 12px;
font-size: 12px;
color: #93a099;
text-align: center;
}
/* Footer */
.sw-actions {
padding: 18px 26px 22px;
border-top: 1px solid #f0f2f0;
margin-top: 12px;
display: flex;
align-items: center;
justify-content: space-between;
gap: 16px;
flex-wrap: wrap;
}
.sw-btn-back {
display: flex;
align-items: center;
gap: 8px;
background: #fff;
color: #37453d;
border: 1px solid #d4d9d4;
border-radius: 9px;
padding: 10px 18px;
font-size: 13px;
font-weight: 600;
cursor: pointer;
font-family: inherit;
}
.sw-btn-save {
display: flex;
align-items: center;
gap: 8px;
background: linear-gradient(120deg,#5fa832,#2f8fb0);
color: #fff;
border: none;
border-radius: 9px;
padding: 11px 24px;
font-size: 13.5px;
font-weight: 700;
cursor: pointer;
font-family: inherit;
box-shadow: 0 4px 12px rgba(95,168,50,.3);
}
/* Modals (Pricebook/Currency confirm + Generate Token) */
.sw-modal-overlay {
position: fixed;
inset: 0;
/* Bumped once the Generate Token modal started being portaled to
document.body (see the JS portalModal()/renderedCallback comment) —
as a direct child of body it now needs to out-rank Salesforce's own
global overlays (toasts, spinners) rather than just local siblings. */
z-index: 9000;
background: rgba(23,43,32,.42);
backdrop-filter: blur(3px);
display: flex;
/* flex-start + margin:auto on .sw-modal (below) instead of
align-items:center: centering via align-items clips overflow evenly
off BOTH the top and bottom with no way to reach it once the modal
is taller than the viewport (happened at 75% zoom but not 50%).
margin:auto centers the box only when there's spare room; once it
doesn't fit, the box simply starts at the top and the overlay's own
scroll (below) reaches the rest — never a hard, unreachable clip. */
align-items: flex-start;
justify-content: center;
padding: 24px;
overflow-y: auto;
}
.sw-modal {
width: min(460px, 100%);
max-height: 86vh;
overflow-y: auto;
background: #fff;
border-radius: 20px;
box-shadow: 0 24px 60px -18px rgba(23,43,32,.55), 0 0 0 1px rgba(95,168,50,.12);
margin: auto 0;
}
.sw-modal_narrow { text-align: center; }
.gen-modal {
width: min(520px, 100%);
text-align: left;
/* Top-right corner squared off: with the modal portaled to document.body,
the overlay's own scrollbar track sits right against this corner and
made the curve look broken/notched. Keeping only the top-left corner
rounded avoids that clash. */
border-radius: 20px 0 20px 20px;
/* This modal now keeps its logo/title header and Close/Generate Token
footer always visible, scrolling only the checklist + fields between
them — so the modal itself becomes a fixed-height flex column instead
of one big scrolling block (the base .sw-modal overflow-y:auto above
is overridden here). */
max-height: 86vh;
overflow: hidden;
display: flex;
flex-direction: column;
}
.gen-modal .gen-token-header { border-radius: 20px 0 0 0; }
.gen-token-header-fixed {
flex-shrink: 0;
background: linear-gradient(120deg, #f4faee 0%, #eaf3fb 100%);
}
.gen-token-fixed-title {
margin: 46px 34px 0;
padding-bottom: 14px;
font-size: 20px;
font-weight: 800;
letter-spacing: -.02em;
text-align: center;
background: linear-gradient(100deg,#5fa832,#2f8fb0);
-webkit-background-clip: text;
background-clip: text;
color: transparent;
}
.gen-token-scroll-body {
flex: 1 1 auto;
overflow-y: auto;
min-height: 0;
}
.gen-token-footer-fixed {
flex-shrink: 0;
padding: 16px 34px 26px;
background: linear-gradient(180deg, #f4faee 0%, #eaf3fb 100%);
border-top: 1px solid #e0e9df;
}
.gen-token-footer-fixed .sw-modal-actions { margin-top: 0; }
.sw-modal-accent {
height: 6px;
background: linear-gradient(90deg,#5fa832 0%,#3f9a86 50%,#2f8fb0 100%);
}
.sw-modal-body {
padding: 30px 34px 34px;
background: linear-gradient(180deg, #f4faee 0%, #eaf3fb 100%);
}
.sw-modal-body_center { text-align: center; padding-top: 16px; }
.sw-modal-title {
margin: 0 0 6px;
font-size: 22px;
font-weight: 800;
letter-spacing: -.02em;
background: linear-gradient(100deg,#5fa832,#2f8fb0);
-webkit-background-clip: text;
background-clip: text;
color: transparent;
}
.sw-modal-note {
font-size: 13px;
color: #37453d;
margin: 6px 0;
}
.sw-modal-field { margin-top: 16px; }
.sw-modal-label {
display: block;
font-size: 12.5px;
font-weight: 600;
margin-bottom: 6px;
color: #37453d;
}
.gen-token-hint { font-weight: 400; color: #93a099; }
.req { color: rgb(194, 57, 52); }
.sw-modal-footnote {
font-size: 12.5px;
color: #6b786f;
margin-top: 10px;
display: block;
}
.sw-modal-actions {
display: flex;
align-items: center;
justify-content: flex-end;
gap: 14px;
margin-top: 22px;
flex-wrap: wrap;
}
.btn-success {
display: inline-flex;
align-items: center;
gap: 7px;
background: linear-gradient(120deg,#5fa832 0%,#3f9a86 55%,#2f8fb0 100%);
color: #fff;
border: none;
border-radius: 10px;
padding: 12px 24px;
font-size: 14px;
font-weight: 700;
cursor: pointer;
font-family: inherit;
box-shadow: 0 8px 20px -8px rgba(58,150,120,.6);
}
.sw-modal-secondary {
display: inline-flex;
align-items: center;
gap: 7px;
/* background: #fff; */
background: rgb(241, 243, 241);
color: #37453d;
border: 1px solid #d4d9d4;
border-radius: 10px;
padding: 12px 24px;
font-size: 14px;
font-weight: 600;
cursor: pointer;
font-family: inherit;
}
/* Check Credential result modal */
/* Now nested inside .sw-modal-body (which already supplies the
linear-gradient background + accent-bar height shared with the other
popups) — this just adds the extra vertical breathing room this modal
needs on top of that shared padding/background. */
.credcheck-modal {
padding-top: 26px;
padding-bottom: 20px;
text-align: center;
}
.credcheck-spinner-ring {
width: 46px;
height: 46px;
margin: 0 auto 20px;
border-radius: 50%;
border: 4px solid #e4ebe6;
border-top-color: #5fa832;
animation: sw-spin .8s linear infinite;
}
.credcheck-icon {
width: 56px;
height: 56px;
margin: 0 auto 18px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
}
.credcheck-icon_success {
background: linear-gradient(120deg,#5fa832,#3f9a86);
box-shadow: 0 8px 20px -8px rgba(58,150,120,.6);
}
.credcheck-icon_error {
background: #c23934;
box-shadow: 0 8px 20px -8px rgba(194,57,52,.5);
}
.credcheck-title {
margin: 0 0 8px;
font-size: 17px;
font-weight: 800;
color: #1c2b23;
}
.credcheck-sub {
margin: 0 0 22px;
font-size: 13px;
color: #6b786f;
line-height: 1.5;
}
/* Generate Token modal specifics */
.gen-token-store-banner {
display: flex;
align-items: center;
gap: 10px;
background: linear-gradient(120deg,#f4faee 0%,#eaf3fb 100%);
border: 1px solid #dce8e2;
border-radius: 10px;
padding: 10px 14px;
margin-bottom: 16px;
}
.gen-token-store-badge {
width: 26px;
height: 26px;
flex-shrink: 0;
display: inline-flex;
align-items: center;
justify-content: center;
color: #5fa832;
}
.gen-token-store-badge-img {
width: 100%;
height: 100%;
object-fit: cover;
}
.gen-token-store-url {
flex: 1;
min-width: 0;
font-size: 14px;
font-weight: 700;
color: #26332b;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.gen-token-steps-title {
font-size: 13px;
font-weight: 700;
color: #37453d;
margin: 0 0 6px;
}
.gen-token-step-list {
/* SLDS resets ol/ul to list-style:none by default — restore real
numbering so "1. 2. 3. 4." actually render. */
list-style: decimal outside;
margin: 0 0 16px;
padding-left: 20px;
font-size: 13px;
color: #5f6d63;
line-height: 1.6;
}
.gen-token-step-list li { display: list-item; }
/* Large rounded green header with a centered icon, replacing the thin
sw-modal-accent bar + plain title for this specific modal only. */
.gen-token-header {
position: relative;
height: 104px;
background: linear-gradient(115deg,#84c25c 0%,#5fa832 55%,#3f9a86 100%);
border-radius: 20px 20px 0 0;
}
.gen-token-header-icon {
position: absolute;
left: 50%;
bottom: -40px;
transform: translateX(-50%);
width: 92px;
height: 92px;
border-radius: 50%;
background: #fff;
color: #5fa832;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 12px 26px -8px rgba(23,43,32,.35), 0 0 0 6px rgba(255,255,255,.6);
}
/* Room for the icon circle hanging below the header edge, on this modal only. */
.gen-modal .sw-modal-body { padding-top: 52px; }
/* Title now sits in the fixed header above; the scrollable body itself no
longer needs the extra top padding reserved for the icon circle when the
fixed title block is already providing that space. */
.gen-modal .gen-token-scroll-body { padding-top: 18px; }
.gen-token-header-logo {
width: 56px;
height: 56px;
object-fit: contain;
}
/* Highlighted checklist box, replacing the plain "Before clicking..."
paragraph + list. */
.gen-token-checklist-box {
background: linear-gradient(120deg,#f4faee 0%,#eaf3fb 100%);
border: 1px solid #e0e9df;
border-radius: 12px;
padding: 16px 18px;
margin-bottom: 16px;
box-shadow: 0 6px 18px -12px rgba(23,43,32,.22);
}
.gen-token-checklist-title {
display: flex;
align-items: center;
gap: 8px;
font-size: 13px;
font-weight: 700;
color: #37453d;
margin-bottom: 8px;
}
.gen-token-check-badge {
width: 20px;
height: 20px;
border-radius: 6px;
background: #5fa832;
display: inline-flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
}
.gen-token-checklist-box .gen-token-step-list {
margin-bottom: 12px;
}
.gen-token-step-list b { color: #37453d; }
.gen-token-guide-row {
display: flex;
gap: 8px;
font-size: 12.5px;
color: #5f6d63;
line-height: 1.5;
border-top: 1px solid #dbe6d8;
padding-top: 12px;
}
.gen-token-guide-row svg { flex-shrink: 0; margin-top: 1px; }
.gen-token-guide-link {
font-weight: 700;
color: #5fa832;
text-decoration: underline;
}
.gen-token-guide-link:hover {
color: #47821f;
}
.gen-token-submit-btn {
background: linear-gradient(120deg,#5fa832,#2f8fb0);
box-shadow: 0 8px 22px -8px rgba(23,43,32,.45);
transition: filter .15s, opacity .15s;
}
.gen-token-submit-btn:hover {
filter: brightness(1.05);
}
/* Blurred/disabled until Client ID + Client Secret are both filled in. */
.gen-token-submit-btn_disabled {
filter: blur(1.5px) grayscale(.3);
opacity: .55;
cursor: not-allowed;
box-shadow: none;
}
.gen-token-submit-btn_disabled:hover {
filter: blur(1.5px) grayscale(.3);
}
.gen-token-redirect-row {
display: flex;
align-items: flex-start;
gap: 10px;
background: linear-gradient(120deg,#f4faee 0%,#eaf3fb 100%);
border: 1px solid #dce8e2;
border-radius: 10px;
padding: 12px 14px;
box-shadow: 0 6px 18px -12px rgba(23,43,32,.22);
cursor: pointer;
}
.gen-token-redirect-uri {
flex: 1;
min-width: 0;
font-size: 12.5px;
color: #2f6fb0;
font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
line-height: 1.5;
word-break: break-all;
}
.gen-token-decoy {
position: absolute;
left: -9999px;
width: 1px;
height: 1px;
opacity: 0;
}
/* Client ID / Client Secret are plain native inputs (not lightning-input):
lightning-input renders in its own shadow DOM, so its background/border
can't reliably be restyled from here — the box kept turning white on
focus/error regardless of the styling hooks tried. A native <input>
gives full, permanent control over the box's look in every state. */
.gen-token-input {
width: 100%;
box-sizing: border-box;
font: inherit;
font-size: 13.5px;
color: #26332b;
background: linear-gradient(120deg,#f4faee 0%,#eaf3fb 100%);
border: 1px solid #dce8e2;
border-radius: 9px;
padding: 11px 14px;
margin-top: 10px;
box-shadow: 0 6px 18px -12px rgba(23,43,32,.22);
outline: none;
}
.gen-token-input:focus {
border-color: #5fa832;
background: linear-gradient(120deg,#f4faee 0%,#eaf3fb 100%);
}
.gen-token-input::placeholder { color: #93a099; }
.gen-token-input:read-only { cursor: text; }
.gen-token-generating {
text-align: center;
padding: 10px 0 4px;
}
.gen-token-generating-heading {
margin: 0 0 6px;
text-align: center;
font-size: 21px;
font-weight: 800;
letter-spacing: -.02em;
background: linear-gradient(100deg,#5fa832,#2f8fb0);
-webkit-background-clip: text;
background-clip: text;
color: transparent;
}
.gen-token-spinner-ring {
width: 100px;
height: 100px;
margin: 24px auto 0;
border-radius: 50%;
border: 6px solid #eef2ec;
border-top-color: #5fa832;
border-right-color: #3f9a86;
animation: sw-spin 0.9s linear infinite;
box-shadow: 0 12px 30px -14px rgba(23,43,32,.35);
display: flex;
align-items: center;
justify-content: center;
}
.gen-token-spinner-badge {
width: 40px;
height: 40px;
border-radius: 12px;
background: linear-gradient(120deg,#f4faee,#eaf3fb);
color: #5fa832;
display: flex;
align-items: center;
justify-content: center;
/* counter-rotate so the icon stays upright while the ring spins */
animation: sw-spin 0.9s linear infinite reverse;
}
.gen-token-generating-title {
font-size: 16px;
font-weight: 800;
color: #1c2b23;
margin: 20px 0 6px;
}
.gen-token-generating-sub {
font-size: 12.5px;
color: #6b786f;
max-width: 320px;
margin: 0 auto 14px;
}
.gen-token-wait-pill {
display: inline-flex;
align-items: center;
gap: 8px;
background: linear-gradient(120deg,#f4faee 0%,#eaf3fb 100%);
border: 1px solid #dce8e2;
border-radius: 999px;
padding: 8px 16px;
font-size: 12.5px;
font-weight: 700;
color: #4f8a24;
box-shadow: 0 6px 18px -12px rgba(23,43,32,.22);
}
.gen-token-wait-dot {
width: 8px;
height: 8px;
border-radius: 50%;
background: #5fa832;
animation: sw-pulse 1.1s ease-in-out infinite;
flex-shrink: 0;
}
.gen-token-cancel-row {
display: flex;
justify-content: center;
margin-top: 14px;
}
@media (max-width: 1080px) {
.sw-panels { grid-template-columns: 1fr; }
.field-row { grid-template-columns: 1fr; }
.field-label { margin-bottom: 2px; }
}
@media (max-width: 560px) {
.sw-hero { flex-direction: column; align-items: stretch; }
.hero-side_right { justify-content: flex-start; }
.hero-text_right { text-align: left; }
}
@media (max-width: 1300px){
.sw-panels {
display:flex;
flex-direction: column;
}
.sw-header-right{
display: flex;
flex-direction: column;
gap: 14px;
margin-top: 60px;;
}
}/* ============================================================
Custom in-component toasts (replaces ShowToastEvent). Success uses the
brand green→teal gradient reference; error uses red. Added by UI packaging.
============================================================ */
.sw-toast-container { position: fixed; top: 16px; left: 50%; transform: translateX(-50%); z-index: 9999; display: flex; flex-direction: column; align-items: center; gap: 10px; width: 100%; max-width: 420px; pointer-events: none; }
.sw-toast { display: flex; align-items: flex-start; gap: 10px; padding: 14px 16px; border-radius: 10px; box-shadow: 0 12px 30px -10px rgba(23,43,32,.45); color: #fff; width: 100%; box-sizing: border-box; pointer-events: auto; animation: sw-toast-in 180ms ease; }
@keyframes sw-toast-in { from { opacity: 0; transform: translateY(-10px); } to { opacity: 1; transform: translateY(0); } }
.sw-toast-icon { flex-shrink: 0; font-size: 15px; line-height: 1.3; font-weight: 700; }
.sw-toast-body { flex: 1; min-width: 0; }
.sw-toast-title { font-weight: 800; font-size: 13.5px; line-height: 1.3; }
.sw-toast-message { font-size: 12.5px; line-height: 1.4; opacity: .95; margin-top: 2px; word-break: break-word; }
.sw-toast-close { flex-shrink: 0; background: transparent; border: none; color: inherit; opacity: .85; cursor: pointer; font-size: 18px; line-height: 1; padding: 0; font-family: inherit; }
.sw-toast-close:hover { opacity: 1; }
.sw-toast-success { background: linear-gradient(120deg, var(--smepro-green), var(--smepro-teal)); }
.sw-toast-error { background: linear-gradient(120deg, #e9923d, #b56a1f); }
.sw-toast-warning { background: #f59e0b; color: #1f2937; }
.sw-toast-info { background: #3b7ec4; }