// Voiced — Carbon Design System, compiled with self-hosted IBM Plex for offline use. // Font-face emission from Carbon is disabled so we can serve the fonts ourselves // instead of pulling them from IBM's CDN (the app must work with no network). @use '@carbon/react' with ( $css--font-face: false, $use-akamai-cdn: false ); /* ---------- IBM Plex (bundled in /public/fonts) ---------- */ @font-face { font-family: 'IBM Plex Sans'; font-style: normal; font-weight: 300; font-display: swap; src: url('/fonts/IBMPlexSans-Light.woff2') format('woff2'); } @font-face { font-family: 'IBM Plex Sans'; font-style: italic; font-weight: 300; font-display: swap; src: url('/fonts/IBMPlexSans-LightItalic.woff2') format('woff2'); } @font-face { font-family: 'IBM Plex Sans'; font-style: normal; font-weight: 400; font-display: swap; src: url('/fonts/IBMPlexSans-Regular.woff2') format('woff2'); } @font-face { font-family: 'IBM Plex Sans'; font-style: italic; font-weight: 400; font-display: swap; src: url('/fonts/IBMPlexSans-Italic.woff2') format('woff2'); } @font-face { font-family: 'IBM Plex Sans'; font-style: normal; font-weight: 500; font-display: swap; src: url('/fonts/IBMPlexSans-Medium.woff2') format('woff2'); } @font-face { font-family: 'IBM Plex Sans'; font-style: italic; font-weight: 500; font-display: swap; src: url('/fonts/IBMPlexSans-MediumItalic.woff2') format('woff2'); } @font-face { font-family: 'IBM Plex Sans'; font-style: normal; font-weight: 600; font-display: swap; src: url('/fonts/IBMPlexSans-SemiBold.woff2') format('woff2'); } @font-face { font-family: 'IBM Plex Sans'; font-style: italic; font-weight: 600; font-display: swap; src: url('/fonts/IBMPlexSans-SemiBoldItalic.woff2') format('woff2'); } @font-face { font-family: 'IBM Plex Sans'; font-style: normal; font-weight: 700; font-display: swap; src: url('/fonts/IBMPlexSans-Bold.woff2') format('woff2'); } @font-face { font-family: 'IBM Plex Sans'; font-style: italic; font-weight: 700; font-display: swap; src: url('/fonts/IBMPlexSans-BoldItalic.woff2') format('woff2'); } @font-face { font-family: 'IBM Plex Mono'; font-style: normal; font-weight: 400; font-display: swap; src: url('/fonts/IBMPlexMono-Regular.woff2') format('woff2'); } @font-face { font-family: 'IBM Plex Mono'; font-style: normal; font-weight: 500; font-display: swap; src: url('/fonts/IBMPlexMono-Medium.woff2') format('woff2'); } @font-face { font-family: 'IBM Plex Mono'; font-style: normal; font-weight: 600; font-display: swap; src: url('/fonts/IBMPlexMono-SemiBold.woff2') format('woff2'); } /* ---------- App shell ---------- */ html, body, #root { height: 100%; } body { margin: 0; background-color: var(--cds-background); color: var(--cds-text-primary); } .voiced-brand { display: flex; align-items: center; gap: 0.75rem; min-width: 0; } .voiced-brand__logo { height: 1.25rem; width: auto; display: block; } .voiced-brand__divider { width: 1px; height: 1.25rem; background: var(--cds-border-subtle-01); } .voiced-brand__product { font-weight: 600; letter-spacing: 0.02em; white-space: nowrap; } .voiced-header-action { display: flex; align-items: center; gap: 0.5rem; } // Views stay mounted while hidden so their state survives navigation. [hidden] { display: none !important; } .voiced-toasts { position: fixed; top: 3.5rem; /* below the 3rem Carbon header */ right: 1rem; z-index: 9100; display: flex; flex-direction: column; gap: 0.5rem; max-width: calc(100vw - 2rem); pointer-events: none; } .voiced-toasts .cds--toast-notification { pointer-events: auto; margin: 0; } .voiced-page { padding: 2rem; max-width: 1600px; margin: 0 auto; width: 100%; box-sizing: border-box; } .voiced-page__title { margin-bottom: 0.25rem; } .voiced-page__subtitle { color: var(--cds-text-secondary); margin-bottom: 2rem; } .voiced-stack > * + * { margin-top: 1.5rem; } .voiced-row-gap { display: flex; flex-wrap: wrap; gap: 1rem; align-items: flex-end; } .voiced-muted { color: var(--cds-text-secondary); } .voiced-empty { padding: 3rem 1rem; text-align: center; color: var(--cds-text-secondary); } /* ---------- PDF preview column ---------- */ .voiced-page-setup { margin-bottom: 1rem; } .voiced-page-setup__row { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 1rem; } .voiced-page-setup__extra { margin-top: 0.75rem; } .voiced-page-setup__field { min-width: 11rem; flex: 1 1 11rem; } .voiced-page-setup__field .cds--label { display: block; margin-bottom: 0.5rem; } .voiced-page-setup__footer { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem 1rem; margin-top: 0.75rem; } .voiced-page-setup__note { font-size: 0.75rem; flex: 1 1 12rem; } .voiced-template-picker__note { margin-bottom: 1rem; font-size: 0.875rem; } .voiced-template-picker__status { flex: 1 1 auto; align-self: center; padding-left: 1rem; font-size: 0.75rem; } .voiced-template-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(12rem, 1fr)); gap: 1rem; } .voiced-template-tile { display: flex; flex-direction: column; gap: 0.75rem; height: 100%; min-height: 0; box-sizing: border-box; } .voiced-template-tile--selected { outline: 2px solid var(--cds-focus); outline-offset: -2px; } .voiced-template-tile__thumb { display: block; width: 100%; aspect-ratio: 420 / 594; object-fit: cover; border: 1px solid var(--cds-border-subtle); background: var(--cds-layer); } .voiced-template-tile__head { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; } .voiced-template-tile__name { font-weight: 600; } .voiced-template-tile__check { flex: none; fill: var(--cds-support-success); } .voiced-template-tile__tags { display: flex; flex-wrap: wrap; gap: 0.25rem; } .voiced-template-tile__tags .cds--tag { margin: 0; } .voiced-pdf-preview { display: flex; flex-direction: column; gap: 0.5rem; min-width: 0; } .voiced-pdf-preview__status { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 0.25rem 1rem; min-height: 2rem; } .voiced-pdf-preview__chips, .voiced-pdf-preview__actions { display: flex; align-items: center; gap: 0.5rem; } .voiced-pdf-preview__empty { display: flex; align-items: center; justify-content: center; height: 12rem; background: var(--cds-layer-accent); color: var(--cds-text-secondary); } .voiced-pdf-viewer { display: flex; flex-direction: column; gap: 0.5rem; min-width: 0; } .voiced-pdf-viewer__bar { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 0.5rem 1rem; } .voiced-pdf-viewer__zoom { flex: 0 1 18rem; } .voiced-pdf-viewer__page { font-size: 0.875rem; color: var(--cds-text-secondary); white-space: nowrap; } .voiced-pdf-preview__scroll { height: calc(100vh - 25rem); min-height: 20rem; overflow: auto; background: var(--cds-layer-accent); } .voiced-pdf-viewer--focus .voiced-pdf-preview__scroll { height: calc(100vh - 12rem); } /* The wrapper is as wide as the widest page so a zoomed page scrolls instead of being clipped. */ .voiced-pdf-preview__pages { box-sizing: border-box; display: flex; flex-direction: column; align-items: center; gap: 16px; min-width: 100%; width: max-content; padding: 16px; } .voiced-pdf-preview__page { flex: none; background: #ffffff; box-shadow: 0 1px 4px rgba(0, 0, 0, 0.25); } .voiced-pdf-preview__canvas { display: block; width: 100%; height: 100%; } .voiced-pdf-focus .cds--modal-container { width: 96vw; max-width: 96vw; height: 94vh; max-height: 94vh; } .voiced-pdf-issues { width: 22rem; max-width: 80vw; max-height: 20rem; overflow: auto; padding: 0.75rem 1rem; } .voiced-pdf-issues__list { list-style: none; margin: 0; padding: 0; } .voiced-pdf-issues__item + .voiced-pdf-issues__item { margin-top: 0.75rem; } .voiced-pdf-issues__head { display: flex; align-items: center; gap: 0.5rem; } .voiced-pdf-issues__message { margin: 0.25rem 0 0; font-size: 0.875rem; } .voiced-tag--warn.cds--tag { background-color: var(--cds-support-warning); color: #161616; } /* ---------- export feedback ---------- */ .voiced-notice-actions { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 0.5rem; } .voiced-export-split { display: inline-flex; align-items: stretch; } .voiced-diagnostics__check { padding: 0.5rem 0; border-bottom: 1px solid var(--cds-border-subtle-01); } .voiced-diagnostics__head { display: flex; align-items: center; gap: 0.5rem; } .voiced-diagnostics__label { flex: 1 1 auto; min-width: 0; } .voiced-diagnostics__ms { color: var(--cds-text-secondary); font-size: 0.75rem; white-space: nowrap; } .voiced-diagnostics__detail { margin: 0.25rem 0 0; color: var(--cds-text-secondary); font-size: 0.75rem; white-space: pre-wrap; overflow-wrap: anywhere; } /* ---------- Logo preview (Settings -> Branding) ---------- */ .voiced-logo-preview { display: flex; flex-wrap: wrap; gap: 1rem; } .voiced-logo-preview__item { margin: 0; width: 14rem; } .voiced-logo-preview__surface { display: flex; align-items: center; justify-content: center; box-sizing: border-box; height: 6rem; padding: 1rem; border: 1px solid var(--cds-border-subtle-01); overflow: hidden; img { display: block; max-width: 100%; max-height: 4rem; object-fit: contain; } } .voiced-logo-preview__surface--light { background: #ffffff; } .voiced-logo-preview__surface--dark { background: #161616; } .voiced-logo-preview__chip { display: flex; box-sizing: border-box; max-width: 100%; padding: 0.5rem 0.75rem; background: #ffffff; border-radius: 0.5rem; img { max-height: 3rem; } } .voiced-logo-preview__item figcaption { margin-top: 0.5rem; font-size: 0.75rem; } /* ---------- Settings: Data tab ---------- */ .voiced-section-title { font-size: 1.25rem; font-weight: 400; margin-bottom: 0.5rem; } .voiced-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 0.75rem; margin-top: 1rem; } .voiced-list { margin-left: 1.25rem; list-style: disc; } /* ---------- Invoice history and detail ---------- */ .voiced-num { text-align: right; } .voiced-history__fy { font-size: 1.25rem; font-weight: 400; margin-bottom: 0.5rem; } .voiced-history__tiles, .voiced-detail__tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr)); gap: 1rem; margin-bottom: 1.5rem; } .voiced-history__amount, .voiced-detail__amount { font-size: 1.75rem; font-weight: 400; } .voiced-history__tile--overdue { border-left: 4px solid var(--cds-support-error); } .voiced-history__filters { display: grid; grid-template-columns: minmax(14rem, 2fr) repeat(4, minmax(9rem, 1fr)) auto; gap: 1rem; align-items: end; margin-bottom: 1rem; } .voiced-history__export { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; margin-bottom: 1rem; } .voiced-history__row { cursor: pointer; } .voiced-history__totals { display: flex; flex-wrap: wrap; gap: 0.5rem 2rem; padding: 0.75rem 1rem; background: var(--cds-layer-accent); border-top: 1px solid var(--cds-border-subtle); } .voiced-detail__head { display: flex; flex-wrap: wrap; align-items: center; gap: 0.75rem; margin-top: 1rem; } .voiced-detail__actions { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; margin: 1rem 0; } .voiced-detail__grid { display: grid; grid-template-columns: minmax(0, 3fr) minmax(0, 2fr); gap: 2rem; align-items: start; } @media (max-width: 1100px) { .voiced-detail__grid, .voiced-history__filters { grid-template-columns: 1fr; } } .voiced-detail__h2 { font-size: 1.25rem; font-weight: 400; margin-bottom: 0.75rem; } .voiced-detail__parties { display: grid; grid-template-columns: 1fr 1fr; gap: 2rem; } .voiced-detail__field { margin-bottom: 0.75rem; } .voiced-detail__pre { white-space: pre-line; } .voiced-detail__totals { margin: 1rem 0 0.5rem auto; max-width: 22rem; } .voiced-detail__totals > div { display: flex; justify-content: space-between; padding: 0.25rem 0; } .voiced-detail__grand { border-top: 1px solid var(--cds-border-strong); font-weight: 600; } .voiced-detail__preview { position: sticky; top: 4rem; } .voiced-detail__unarchived { padding: 1.5rem; background: var(--cds-layer-accent); } .voiced-detail__unarchived p { margin-bottom: 1rem; }