Download src/app/student-os.css from asnannp/DocDoeAI: direct link, hf CLI and curl.
- Browser
- Download file 45.3 kB
-
https://huggingface.co/spaces/asnannp/DocDoeAI/resolve/main/src/app/student-os.css
- Command line
-
hf download hf://spaces/asnannp/DocDoeAI/src/app/student-os.css
-
curl -L -o student-os.css https://huggingface.co/spaces/asnannp/DocDoeAI/resolve/main/src/app/student-os.css
45.3 kB
| /* DocDoe Student OS β shared product surface polish */ | |
| .docdoe-student-os { | |
| --student-canvas: #ffffff; | |
| --student-panel: #ffffff; | |
| --student-ink: #171717; | |
| --student-ink-2: #404040; | |
| --student-muted: #666666; | |
| --student-muted-2: #707070; | |
| --student-line: #ebebeb; | |
| --student-line-strong: #c9c9c9; | |
| --student-accent: var(--student-ink); | |
| --student-accent-hover: #292929; | |
| --student-accent-soft: #f5f5f5; | |
| --student-rail: #fafafa; | |
| --student-scroll-thumb: #c9c9c9; | |
| --student-scroll-hover: #a3a3a3; | |
| --student-purple: var(--student-accent); | |
| --student-purple-hover: var(--student-accent-hover); | |
| --student-purple-soft: var(--student-accent-soft); | |
| --student-radius-sm: 8px; | |
| --student-radius-md: 12px; | |
| --student-radius-lg: 14px; | |
| --student-radius-xl: 18px; | |
| --student-shadow-sm: 0 1px 2px rgba(15, 17, 23, 0.03); | |
| --student-shadow-card: | |
| 0 1px 2px rgba(15, 17, 23, 0.03), | |
| 0 8px 24px rgba(15, 17, 23, 0.04); | |
| --student-shadow-lift: | |
| 0 2px 4px rgba(15, 17, 23, 0.04), | |
| 0 14px 32px rgba(15, 17, 23, 0.08); | |
| --student-ease: cubic-bezier(0.23, 1, 0.32, 1); | |
| --student-ease-out: cubic-bezier(0.16, 1, 0.3, 1); | |
| --student-motion-instant: 90ms; | |
| --student-motion-fast: 150ms; | |
| --student-motion-base: 200ms; | |
| --student-motion-slow: 260ms; | |
| --student-motion-settle: 320ms; | |
| --student-stagger-step: 40ms; | |
| --student-stagger-cap: 5; | |
| color-scheme: light; | |
| color: var(--student-ink); | |
| background: var(--student-canvas); | |
| -webkit-font-smoothing: antialiased; | |
| -moz-osx-font-smoothing: grayscale; | |
| --student-sidebar-w: 248px; | |
| --student-header-h: 56px; | |
| --student-bottom-nav-h: 64px; | |
| --student-safe-bottom: env(safe-area-inset-bottom, 0px); | |
| --student-safe-top: env(safe-area-inset-top, 0px); | |
| --student-shell-bottom: calc( | |
| var(--student-bottom-nav-h) + var(--student-safe-bottom) | |
| ); | |
| overflow-x: clip; | |
| max-width: 100%; | |
| } | |
| @media (min-width: 1024px) { | |
| .docdoe-student-os { | |
| --student-header-h: 68px; | |
| --student-shell-bottom: 0px; | |
| } | |
| } | |
| .docdoe-student-os ::selection { | |
| background: rgba(23, 23, 22, 0.14); | |
| } | |
| .docdoe-student-os :is(h1, h2) { | |
| text-wrap: balance; | |
| } | |
| .docdoe-student-os :is(p, li, figcaption) { | |
| text-wrap: pretty; | |
| } | |
| .docdoe-student-os, | |
| .docdoe-student-os * { | |
| scrollbar-color: var(--student-scroll-thumb) transparent; | |
| scrollbar-width: thin; | |
| } | |
| .docdoe-student-os ::-webkit-scrollbar { | |
| width: 7px; | |
| height: 7px; | |
| } | |
| .docdoe-student-os ::-webkit-scrollbar-thumb { | |
| border: 2px solid transparent; | |
| border-radius: 999px; | |
| background: var(--student-scroll-thumb); | |
| background-clip: padding-box; | |
| } | |
| .docdoe-student-os ::-webkit-scrollbar-thumb:hover { | |
| background: var(--student-scroll-hover); | |
| background-clip: padding-box; | |
| } | |
| @media (forced-colors: active) { | |
| .docdoe-student-os, | |
| .docdoe-student-os * { | |
| scrollbar-color: auto; | |
| scrollbar-width: auto; | |
| } | |
| .docdoe-student-os ::-webkit-scrollbar-thumb { | |
| background: ButtonText; | |
| } | |
| } | |
| .docdoe-student-os button, | |
| .docdoe-student-os a { | |
| -webkit-tap-highlight-color: transparent; | |
| } | |
| .docdoe-student-os button:not(:disabled), | |
| .docdoe-student-os a[href] { | |
| cursor: pointer; | |
| } | |
| .docdoe-student-os :is(h1, h2, h3, [tabindex="-1"]) { | |
| scroll-margin-top: calc(var(--student-header-h) + 16px); | |
| } | |
| /* Migrate repeated legacy utility colors through the shared product tokens so | |
| muted labels remain readable without changing every page-local component. */ | |
| .docdoe-student-os [class~="text-[#73757c]"] { | |
| color: var(--student-muted) ; | |
| } | |
| .docdoe-student-os [class~="text-[#92949a]"] { | |
| color: var(--student-muted-2) ; | |
| } | |
| /* A few older Student OS surfaces still carry pale metadata utilities. Route | |
| them through the same readable muted token instead of maintaining a second | |
| contrast scale in individual pages. */ | |
| .docdoe-student-os [class~="text-[#6f7484]"], | |
| .docdoe-student-os [class~="text-[#747783]"], | |
| .docdoe-student-os [class~="text-[#7a8190]"], | |
| .docdoe-student-os [class~="text-[#83848d]"], | |
| .docdoe-student-os [class~="text-[#858690]"], | |
| .docdoe-student-os [class~="text-[#858894]"], | |
| .docdoe-student-os [class~="text-[#888993]"], | |
| .docdoe-student-os [class~="text-[#898a94]"], | |
| .docdoe-student-os [class~="text-[#898b95]"], | |
| .docdoe-student-os [class~="text-[#8a8b94]"], | |
| .docdoe-student-os [class~="text-[#8b8c95]"], | |
| .docdoe-student-os [class~="text-[#a8aaaf]"] { | |
| color: var(--student-muted) ; | |
| } | |
| .docdoe-student-os [class~="text-white/30"], | |
| .docdoe-student-os [class~="text-white/40"], | |
| .docdoe-student-os [class~="text-white/45"] { | |
| color: rgb(255 255 255 / 0.68) ; | |
| } | |
| /* Shared card elevation */ | |
| .docdoe-student-os .student-panel { | |
| border: 1px solid var(--student-line); | |
| border-radius: var(--student-radius-lg); | |
| background: var(--student-panel); | |
| box-shadow: var(--student-shadow-card); | |
| } | |
| .docdoe-student-os .student-card-lift { | |
| transition: | |
| transform 170ms var(--student-ease), | |
| border-color 170ms var(--student-ease), | |
| box-shadow 170ms var(--student-ease); | |
| } | |
| @media (hover: hover) and (pointer: fine) { | |
| .docdoe-student-os .student-card-lift:hover { | |
| transform: translateY(-2px); | |
| border-color: var(--student-line-strong); | |
| box-shadow: var(--student-shadow-lift); | |
| } | |
| } | |
| .docdoe-student-os .student-card-lift:active { | |
| transform: translateY(0) scale(0.995); | |
| } | |
| /* Pressable controls */ | |
| .docdoe-student-os .student-press { | |
| transition: | |
| transform 140ms var(--student-ease), | |
| background-color 160ms var(--student-ease), | |
| border-color 160ms var(--student-ease), | |
| box-shadow 160ms var(--student-ease), | |
| color 160ms var(--student-ease); | |
| } | |
| .docdoe-student-os .student-press:active:not(:disabled) { | |
| transform: scale(0.97); | |
| } | |
| .docdoe-student-os .student-press:focus-visible { | |
| outline: 2px solid var(--student-accent); | |
| outline-offset: 2px; | |
| } | |
| /* Quiet eyebrow labels β product, not marketing shout */ | |
| .docdoe-student-os .student-eyebrow { | |
| font-size: 11px; | |
| font-weight: 600; | |
| letter-spacing: 0.04em; | |
| text-transform: uppercase; | |
| color: var(--student-muted); | |
| } | |
| .docdoe-student-os .student-eyebrow-accent { | |
| font-size: 11px; | |
| font-weight: 600; | |
| letter-spacing: 0.04em; | |
| text-transform: uppercase; | |
| color: var(--student-purple); | |
| } | |
| /* Input focus ring */ | |
| .docdoe-student-os .student-input-ring { | |
| transition: | |
| border-color 160ms var(--student-ease), | |
| box-shadow 160ms var(--student-ease); | |
| } | |
| .docdoe-student-os .student-input-ring:focus-within { | |
| border-color: rgba(23, 24, 27, 0.45); | |
| box-shadow: 0 0 0 3px rgba(23, 24, 27, 0.1); | |
| } | |
| /* Page-local classes predate the Student OS tokens. Keep those routes | |
| visually coherent while they are migrated: purple is not a product accent. */ | |
| .docdoe-student-os [class~="text-[#6c43f3]"], | |
| .docdoe-student-os [class~="text-[#6d5ce7]"], | |
| .docdoe-student-os [class~="text-[#5b35e0]"], | |
| .docdoe-student-os [class~="text-[#5a49d6]"], | |
| .docdoe-student-os [class~="text-[#7b5bf0]"], | |
| .docdoe-student-os [class~="text-[#7865e7]"], | |
| .docdoe-student-os [class*="text-violet-"] { | |
| color: var(--student-accent) ; | |
| } | |
| .docdoe-student-os [class~="bg-[#6c43f3]"], | |
| .docdoe-student-os [class~="bg-[#6d5ce7]"], | |
| .docdoe-student-os [class*="bg-violet-"] { | |
| background-color: var(--student-accent) ; | |
| background-image: none ; | |
| } | |
| .docdoe-student-os [class~="bg-[#f1edff]"], | |
| .docdoe-student-os [class~="bg-[#f1ebff]"], | |
| .docdoe-student-os [class~="bg-[#f0edff]"], | |
| .docdoe-student-os [class~="bg-[#f2efff]"], | |
| .docdoe-student-os [class~="bg-[#f7f5ff]"], | |
| .docdoe-student-os [class*="bg-violet-50"] { | |
| background-color: var(--student-accent-soft) ; | |
| background-image: none ; | |
| } | |
| .docdoe-student-os [class*="border-violet-"] { | |
| border-color: var(--student-line-strong) ; | |
| } | |
| .docdoe-student-os [class*="from-[#f1edff]"], | |
| .docdoe-student-os [class*="from-[#f4edff]"], | |
| .docdoe-student-os [class*="to-[#fbfaff]"] { | |
| --tw-gradient-from: var(--student-accent-soft) ; | |
| --tw-gradient-to: var(--student-panel) ; | |
| } | |
| .docdoe-student-os :is(a, button, input, select, textarea):focus-visible { | |
| outline: 2px solid var(--student-accent); | |
| outline-offset: 2px; | |
| } | |
| /* The light rail and drawer need the same graphite keyboard cue as content. */ | |
| .docdoe-student-os aside :is(a, button):focus-visible { | |
| outline-color: var(--student-ink); | |
| outline-width: 3px; | |
| } | |
| .docdoe-student-os .student-os-sheet :is(a, button), | |
| .docdoe-student-os [data-testid="docdoe-page-guide"] :is(a, button), | |
| .docdoe-student-os [role="dialog"] :is(a, button) { | |
| min-height: 44px; | |
| } | |
| @media (max-width: 639px) { | |
| .docdoe-student-os main.student-os-main { | |
| padding-inline: 0; | |
| } | |
| } | |
| /* Shared mobile chrome helpers */ | |
| .docdoe-student-os .student-os-main { | |
| min-height: calc(100dvh - var(--student-header-h)); | |
| padding-bottom: calc(var(--student-shell-bottom) + 12px); | |
| outline: none; | |
| } | |
| @media (min-width: 1024px) { | |
| .docdoe-student-os .student-os-main { | |
| padding-bottom: 5.5rem; | |
| } | |
| } | |
| .docdoe-student-os .student-route-surface { | |
| min-height: inherit; | |
| } | |
| .docdoe-student-os .student-os-header { | |
| min-height: calc(var(--student-header-h) + var(--student-safe-top)); | |
| padding-top: var(--student-safe-top); | |
| } | |
| .docdoe-student-os .student-os-bottom-nav { | |
| height: calc(var(--student-bottom-nav-h) + var(--student-safe-bottom)); | |
| padding-bottom: var(--student-safe-bottom); | |
| } | |
| @keyframes docdoe-mascot-bob { | |
| 0%, | |
| 100% { | |
| transform: translateY(0); | |
| } | |
| 50% { | |
| transform: translateY(-6px); | |
| } | |
| } | |
| .docdoe-mascot-bob { | |
| animation: docdoe-mascot-bob 2.8s ease-in-out infinite; | |
| } | |
| @media (prefers-reduced-motion: reduce) { | |
| .docdoe-mascot-bob { | |
| animation: none; | |
| } | |
| } | |
| /* Prevent iOS input zoom without fighting desktop scale */ | |
| @media (max-width: 767px) { | |
| .docdoe-student-os input, | |
| .docdoe-student-os select, | |
| .docdoe-student-os textarea { | |
| font-size: 16px ; | |
| } | |
| } | |
| /* Full-bleed fixed sheets above bottom nav + helper FAB */ | |
| .docdoe-student-os .student-os-sheet { | |
| z-index: 80; | |
| } | |
| /* Horizontal safety for long content rows */ | |
| .docdoe-student-os .student-os-main, | |
| .docdoe-student-os .student-os-main > * { | |
| max-width: 100%; | |
| } | |
| .docdoe-student-os .student-loading-block { | |
| overflow: hidden; | |
| border-radius: 6px; | |
| background: #ebeae5; | |
| background-image: linear-gradient( | |
| 100deg, | |
| transparent 20%, | |
| rgba(255, 255, 255, 0.82) 40%, | |
| transparent 60% | |
| ); | |
| background-position: 120% 0; | |
| background-size: 220% 100%; | |
| animation: student-loading-sheen 1.6s ease-in-out infinite; | |
| } | |
| .docdoe-student-os .student-loading-line { | |
| animation: student-loading-line 1.35s var(--student-ease-out) infinite; | |
| transform-origin: left center; | |
| } | |
| @keyframes student-loading-sheen { | |
| 0% { background-position: 120% 0; } | |
| 100% { background-position: -120% 0; } | |
| } | |
| @keyframes student-loading-line { | |
| 0% { transform: translateX(-110%) scaleX(0.45); } | |
| 55% { transform: translateX(130%) scaleX(0.9); } | |
| 100% { transform: translateX(320%) scaleX(0.45); } | |
| } | |
| @media (prefers-reduced-motion: reduce) { | |
| .docdoe-student-os *, | |
| .docdoe-student-os *::before, | |
| .docdoe-student-os *::after { | |
| scroll-behavior: auto ; | |
| animation-duration: 0.01ms ; | |
| animation-iteration-count: 1 ; | |
| transition-duration: 0.01ms ; | |
| } | |
| .docdoe-student-os .student-card-lift:hover, | |
| .docdoe-student-os .student-card-lift:active, | |
| .docdoe-student-os .student-press:active:not(:disabled) { | |
| transform: none; | |
| } | |
| .docdoe-student-os .student-loading-block { | |
| animation: none ; | |
| opacity: 0.7; | |
| } | |
| .docdoe-student-os .student-loading-line { | |
| width: 40%; | |
| animation: none ; | |
| opacity: 0.7; | |
| transform: none; | |
| } | |
| } | |
| @keyframes docdoe-thinking-pulse { | |
| 0%, | |
| 70%, | |
| 100% { | |
| opacity: 0.28; | |
| transform: translateY(0); | |
| } | |
| 35% { | |
| opacity: 1; | |
| transform: translateY(-1.5px); | |
| } | |
| } | |
| @keyframes tuition-load-sweep { | |
| 0% { | |
| transform: translateX(-120%); | |
| } | |
| 100% { | |
| transform: translateX(360%); | |
| } | |
| } | |
| @keyframes la-plan-load-sweep { | |
| 0% { | |
| transform: translateX(-120%); | |
| } | |
| 100% { | |
| transform: translateX(360%); | |
| } | |
| } | |
| @keyframes la-plan-card-rise { | |
| 0% { | |
| opacity: 0.35; | |
| transform: translateY(6px); | |
| } | |
| 100% { | |
| opacity: 1; | |
| transform: translateY(0); | |
| } | |
| } | |
| @keyframes la-plan-pulse { | |
| 0%, | |
| 100% { | |
| opacity: 0.45; | |
| } | |
| 50% { | |
| opacity: 1; | |
| } | |
| } | |
| .la-plan-load-bar { | |
| animation: la-plan-load-sweep 1.15s cubic-bezier(0.4, 0, 0.2, 1) infinite; | |
| will-change: transform; | |
| } | |
| .la-plan-card-rise { | |
| animation: la-plan-card-rise 0.55s cubic-bezier(0.16, 1, 0.3, 1) both; | |
| } | |
| .la-plan-pulse { | |
| animation: la-plan-pulse 1.1s ease-in-out infinite; | |
| } | |
| /* Quiet indeterminate bar for tuition class prep */ | |
| .tuition-load-bar { | |
| animation: tuition-load-sweep 1.15s cubic-bezier(0.4, 0, 0.2, 1) infinite; | |
| will-change: transform; | |
| } | |
| .docdoe-thinking-dots { | |
| display: inline-flex; | |
| gap: 3px; | |
| } | |
| .docdoe-thinking-dots i { | |
| width: 4px; | |
| height: 4px; | |
| border-radius: 999px; | |
| background: currentColor; | |
| animation: docdoe-thinking-pulse 1.05s ease-in-out infinite; | |
| } | |
| .docdoe-thinking-dots i:nth-child(2) { | |
| animation-delay: 0.13s; | |
| } | |
| .docdoe-thinking-dots i:nth-child(3) { | |
| animation-delay: 0.26s; | |
| } | |
| /* Shared muted labels must remain readable on the app and auth surfaces. */ | |
| [class~="text-[#777873]"], | |
| [class~="text-[#73757c]"], | |
| [class~="text-[#92949a]"], | |
| [class~="text-[#898a85]"] { | |
| color: #5c6170 ; | |
| } | |
| /* Learn Anything uses lighter editorial metadata tokens on a white surface. */ | |
| [class~="text-[#9CA3AF]"], | |
| [class~="text-[#C4C4CC]"] { | |
| color: #62635e ; | |
| } | |
| /* ------------------------------------------------------------------ * | |
| * Entrance choreography | |
| * | |
| * Deliberately CSS-only: the stagger, card rise and progress fill run on the | |
| * compositor with no JavaScript per node, which matters on low-end Android | |
| * where a 40-item grid animated through JS springs drops frames. Only | |
| * transform and opacity are touched. | |
| * ------------------------------------------------------------------ */ | |
| @keyframes student-rise { | |
| from { | |
| opacity: 0; | |
| transform: translate3d(0, 10px, 0); | |
| } | |
| to { | |
| opacity: 1; | |
| transform: translate3d(0, 0, 0); | |
| } | |
| } | |
| @keyframes student-fade { | |
| from { | |
| opacity: 0; | |
| } | |
| to { | |
| opacity: 1; | |
| } | |
| } | |
| /* Staggered children, capped at 6: delay = min(i, 5) * 40ms, so the whole group | |
| settles within 200ms. The 7th sibling onward renders static β a 40-row grid | |
| must never animate 40 nodes, they arrive with the container instead. */ | |
| .docdoe-student-os .student-stagger { | |
| animation: student-fade var(--student-motion-slow) var(--student-ease-out) both; | |
| } | |
| .docdoe-student-os .student-stagger > * { | |
| animation: student-rise 220ms var(--student-ease-out) both; | |
| } | |
| .docdoe-student-os .student-stagger > *:nth-child(1) { animation-delay: 0ms; } | |
| .docdoe-student-os .student-stagger > *:nth-child(2) { animation-delay: 40ms; } | |
| .docdoe-student-os .student-stagger > *:nth-child(3) { animation-delay: 80ms; } | |
| .docdoe-student-os .student-stagger > *:nth-child(4) { animation-delay: 120ms; } | |
| .docdoe-student-os .student-stagger > *:nth-child(5) { animation-delay: 160ms; } | |
| .docdoe-student-os .student-stagger > *:nth-child(6) { animation-delay: 200ms; } | |
| /* Beyond the cap the children stop animating individually and ride the | |
| container's single fade. This is what keeps long lists cheap. */ | |
| .docdoe-student-os .student-stagger > *:nth-child(n + 7) { | |
| animation: none; | |
| } | |
| /* Slower variant for page-level sections, which read as larger blocks. */ | |
| .docdoe-student-os .student-stagger-slow > * { | |
| animation-duration: var(--student-motion-slow); | |
| } | |
| .docdoe-student-os .student-stagger-fade > * { | |
| animation-name: student-fade; | |
| } | |
| /* Standalone rising element. */ | |
| .docdoe-student-os .student-rise { | |
| animation: student-rise var(--student-motion-slow) var(--student-ease-out) both; | |
| } | |
| .docdoe-student-os .student-fade-in { | |
| animation: student-fade var(--student-motion-base) var(--student-ease-out) both; | |
| } | |
| /* Progress fills animate with scaleX (compositor) instead of width (layout), | |
| which is the difference between smooth and janky on a weak GPU. */ | |
| .docdoe-student-os .student-progress-track { | |
| position: relative; | |
| overflow: hidden; | |
| border-radius: 999px; | |
| background: #e6e7e2; | |
| } | |
| .docdoe-student-os .student-progress-fill { | |
| display: block; | |
| height: 100%; | |
| width: 100%; | |
| border-radius: inherit; | |
| background: var(--student-accent); | |
| transform-origin: left center; | |
| transform: scaleX(var(--student-progress, 0)); | |
| transition: transform var(--student-motion-settle) var(--student-ease-out); | |
| } | |
| /* ------------------------------------------------------------------ * | |
| * Tuition focus mode | |
| * | |
| * The tuition surfaces are deliberately dark β it is an intentional | |
| * concentration mode, not an oversight, so it must NOT be "fixed" to match the | |
| * light canvas. It was, however, ~345 hardcoded hex literals spread across 12 | |
| * files with no single source of truth. These tokens are that source: new work | |
| * should reference them, and the legacy literals migrate over time. | |
| * ------------------------------------------------------------------ */ | |
| .docdoe-tuition-focus { | |
| --tuition-canvas: #0d0d0d; | |
| --tuition-surface: #111111; | |
| --tuition-surface-raised: #1a1a1a; | |
| --tuition-border: #2a2a2a; | |
| --tuition-border-strong: #333333; | |
| --tuition-ink: #ffffff; | |
| --tuition-muted: #8b8b8b; | |
| --tuition-success: #10b981; | |
| --tuition-critical: #ef4444; | |
| --tuition-track: rgb(255 255 255 / 0.12); | |
| } | |
| /* Tuition runs on the dark focus surface, so the track tint differs but the | |
| fill still animates with scaleX for the same compositor reason. */ | |
| .tuition-progress-fill { | |
| transform-origin: left center; | |
| transform: scaleX(var(--tuition-progress, 0)); | |
| transition: transform var(--student-motion-settle) var(--student-ease-out); | |
| } | |
| /* Subtle sheen that runs once when a panel mounts β signals "fresh content" | |
| without a spinner. */ | |
| @keyframes student-panel-settle { | |
| from { | |
| opacity: 0; | |
| transform: translate3d(0, 6px, 0) scale(0.995); | |
| } | |
| to { | |
| opacity: 1; | |
| transform: translate3d(0, 0, 0) scale(1); | |
| } | |
| } | |
| .docdoe-student-os .student-panel-settle { | |
| animation: student-panel-settle var(--student-motion-settle) var(--student-ease-out) both; | |
| } | |
| /* Count-up values should not reflow their neighbours as digits change. */ | |
| .docdoe-student-os .student-tabular { | |
| font-variant-numeric: tabular-nums; | |
| font-feature-settings: "tnum"; | |
| } | |
| @media (prefers-reduced-motion: reduce) { | |
| .tuition-load-bar, | |
| .la-plan-load-bar, | |
| .la-plan-card-rise, | |
| .la-plan-pulse, | |
| .docdoe-thinking-dots i { | |
| animation: none; | |
| } | |
| .tuition-load-bar, | |
| .la-plan-load-bar { | |
| width: 40%; | |
| opacity: 0.75; | |
| } | |
| .docdoe-student-os .student-stagger > *, | |
| .docdoe-student-os .student-rise, | |
| .docdoe-student-os .student-fade-in, | |
| .docdoe-student-os .student-panel-settle { | |
| animation: none ; | |
| opacity: 1 ; | |
| transform: none ; | |
| } | |
| .docdoe-student-os .student-progress-fill { | |
| transition: none; | |
| } | |
| } | |
| /* ------------------------------------------------------------------ * | |
| * DocDoe craft layer β shared language for /home, /tuition, /study-chat | |
| * | |
| * Three routes were rewritten against one vocabulary instead of three local | |
| * dialects. The rules that keep it coherent: | |
| * | |
| * - White content and a quiet gray rail. Group through space and typography; | |
| * reserve subtle surfaces for related work, not stacks of promotional cards. | |
| * - One neutral scale, owned by --student-* and exposed through --dd-*. | |
| * No independent warm or blue-gray palette in individual student routes. | |
| * - Hue is status. Green/amber/red carry evidence, revision and failure. | |
| * They are never decoration, so at most one appears per reading band. | |
| * - Motion is 150-250ms ease-out and only ever answers a user action: | |
| * hover, focus, press, and value changes. Nothing animates on its own. | |
| * ------------------------------------------------------------------ */ | |
| .docdoe-student-os { | |
| --dd-paper: var(--student-canvas); | |
| --dd-canvas: var(--student-rail); | |
| --dd-sunk: var(--student-accent-soft); | |
| --dd-panel: var(--student-panel); | |
| --dd-ink: var(--student-ink); | |
| --dd-ink-2: var(--student-ink-2); | |
| --dd-muted: var(--student-muted); | |
| --dd-faint: var(--student-muted-2); | |
| --dd-line: var(--student-line); | |
| --dd-line-strong: var(--student-line-strong); | |
| --dd-positive: #147a5a; | |
| --dd-positive-soft: #eaf4ef; | |
| --dd-positive-line: #cfe4d9; | |
| --dd-attention: #a66b1f; | |
| --dd-attention-soft: #fbf3e7; | |
| --dd-attention-line: #eddcbe; | |
| --dd-critical: #b33a3a; | |
| --dd-critical-soft: #fbedec; | |
| --dd-critical-line: #eed3d1; | |
| /* Board world. Only class/board surfaces may use these, and only the chalk | |
| hairline below may carry a hue inside them. */ | |
| --dd-board: #0b0f0e; | |
| --dd-board-panel: #0e1413; | |
| --dd-board-line: #232a28; | |
| --dd-board-ink: #f2f4f1; | |
| --dd-board-muted: #8f9a92; | |
| --dd-chalk: #ead08c; | |
| --dd-r-sm: 8px; | |
| --dd-r-md: 10px; | |
| --dd-r-lg: 14px; | |
| --dd-r-xl: 18px; | |
| --dd-ease: cubic-bezier(0.16, 1, 0.3, 1); | |
| --dd-ease-soft: cubic-bezier(0.23, 1, 0.32, 1); | |
| --dd-t-fast: 150ms; | |
| --dd-t-base: 200ms; | |
| --dd-t-slow: 250ms; | |
| --dd-t-settle: 320ms; | |
| } | |
| /* ββ Typography atoms βββββββββββββββββββββββββββββββββββββββββββββββ */ | |
| /* 11px tracked caps. The product voice for structure; never a headline. */ | |
| .docdoe-student-os .dd-eyebrow { | |
| font-size: 11px; | |
| font-weight: 600; | |
| letter-spacing: 0.09em; | |
| line-height: 1; | |
| text-transform: uppercase; | |
| color: var(--dd-faint); | |
| } | |
| .docdoe-student-os .dd-eyebrow-ink { | |
| color: var(--dd-ink-2); | |
| } | |
| /* Docket numerals: index numbers, counts, and any figure that must not | |
| reflow while its neighbours change. */ | |
| .docdoe-student-os .dd-mono { | |
| font-family: var(--font-mono), ui-monospace, monospace; | |
| font-variant-numeric: tabular-nums; | |
| font-feature-settings: "tnum"; | |
| letter-spacing: 0.02em; | |
| } | |
| /* Display figures β the hero moment's numbers only. */ | |
| .docdoe-student-os .dd-figure { | |
| font-family: var(--font-display), var(--font-sans), sans-serif; | |
| font-weight: 600; | |
| font-variant-numeric: tabular-nums; | |
| letter-spacing: -0.03em; | |
| line-height: 0.95; | |
| } | |
| /* ββ Structure: rules and tear-lines ββββββββββββββββββββββββββββββββ */ | |
| .docdoe-student-os .dd-rule { | |
| height: 1px; | |
| background: var(--dd-line); | |
| border: 0; | |
| } | |
| .docdoe-student-os .dd-tear { | |
| height: 0; | |
| border: 0; | |
| border-top: 1px dashed var(--dd-line-strong); | |
| } | |
| .docdoe-student-os .dd-rule-vertical { | |
| width: 1px; | |
| align-self: stretch; | |
| background: var(--dd-line); | |
| } | |
| /* ββ Press and focus ββββββββββββββββββββββββββββββββββββββββββββββββ */ | |
| .docdoe-student-os .dd-press { | |
| transition: | |
| transform var(--dd-t-fast) var(--dd-ease), | |
| background-color var(--dd-t-base) var(--dd-ease), | |
| border-color var(--dd-t-base) var(--dd-ease), | |
| color var(--dd-t-base) var(--dd-ease), | |
| box-shadow var(--dd-t-base) var(--dd-ease); | |
| } | |
| .docdoe-student-os .dd-press:active:not(:disabled) { | |
| transform: scale(0.975); | |
| } | |
| .docdoe-student-os .dd-press:focus-visible, | |
| .docdoe-student-os .dd-focusable:focus-visible { | |
| outline: 2px solid var(--dd-ink); | |
| outline-offset: 2px; | |
| } | |
| /* ββ Marks ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */ | |
| /* The product mark. A hairline inset gives the flat ink tile a physical | |
| edge without a glow or gradient. */ | |
| .docdoe-student-os .dd-mark { | |
| display: grid; | |
| place-items: center; | |
| border-radius: var(--dd-r-md); | |
| background: var(--dd-ink); | |
| color: #fff; | |
| box-shadow: inset 0 0 0 1px rgb(255 255 255 / 0.14); | |
| transition: transform var(--dd-t-base) var(--dd-ease); | |
| } | |
| .docdoe-student-os .dd-mark-quiet { | |
| background: var(--dd-sunk); | |
| color: var(--dd-ink); | |
| box-shadow: inset 0 0 0 1px rgb(23 23 22 / 0.05); | |
| } | |
| /* ββ Buttons ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */ | |
| .docdoe-student-os .dd-btn { | |
| display: inline-flex; | |
| align-items: center; | |
| justify-content: center; | |
| gap: 8px; | |
| border-radius: var(--dd-r-md); | |
| font-size: 14px; | |
| font-weight: 600; | |
| letter-spacing: -0.005em; | |
| white-space: nowrap; | |
| } | |
| .docdoe-student-os .dd-btn-ink { | |
| background: var(--dd-ink); | |
| color: #fff; | |
| box-shadow: inset 0 0 0 1px rgb(255 255 255 / 0.1); | |
| } | |
| @media (hover: hover) and (pointer: fine) { | |
| .docdoe-student-os .dd-btn-ink:hover:not(:disabled) { | |
| background: #2b2b29; | |
| } | |
| } | |
| .docdoe-student-os .dd-btn-ink:disabled { | |
| background: #cfcfca; | |
| color: #fbfbfa; | |
| box-shadow: none; | |
| } | |
| .docdoe-student-os .dd-btn-paper { | |
| background: var(--dd-panel); | |
| border: 1px solid var(--dd-line-strong); | |
| color: var(--dd-ink); | |
| } | |
| @media (hover: hover) and (pointer: fine) { | |
| .docdoe-student-os .dd-btn-paper:hover:not(:disabled) { | |
| border-color: #b9b8b1; | |
| background: var(--dd-paper); | |
| } | |
| } | |
| .docdoe-student-os .dd-btn-ghost { | |
| background: transparent; | |
| color: var(--dd-ink-2); | |
| } | |
| @media (hover: hover) and (pointer: fine) { | |
| .docdoe-student-os .dd-btn-ghost:hover:not(:disabled) { | |
| background: var(--dd-sunk); | |
| color: var(--dd-ink); | |
| } | |
| } | |
| /* The inverse button belongs to the board world: white fill, ink text. */ | |
| .docdoe-student-os .dd-btn-board { | |
| background: var(--dd-board-ink); | |
| color: var(--dd-board); | |
| box-shadow: inset 0 0 0 1px rgb(11 15 14 / 0.12); | |
| } | |
| @media (hover: hover) and (pointer: fine) { | |
| .docdoe-student-os .dd-btn-board:hover:not(:disabled) { | |
| background: #fff; | |
| } | |
| } | |
| /* Arrow that answers a hover without moving the layout. */ | |
| .docdoe-student-os .dd-arrow { | |
| transition: transform var(--dd-t-base) var(--dd-ease); | |
| } | |
| .docdoe-student-os .group:hover .dd-arrow, | |
| .docdoe-student-os .group:focus-visible .dd-arrow { | |
| transform: translateX(3px); | |
| } | |
| /* Quiet link: the underline draws from the left on hover instead of a | |
| colour flash, so it reads as navigation rather than a state change. */ | |
| .docdoe-student-os .dd-link { | |
| position: relative; | |
| display: inline-flex; | |
| align-items: center; | |
| gap: 6px; | |
| font-size: 13px; | |
| font-weight: 600; | |
| color: var(--dd-ink-2); | |
| } | |
| .docdoe-student-os .dd-link::after { | |
| content: ""; | |
| position: absolute; | |
| left: 0; | |
| right: 0; | |
| bottom: -2px; | |
| height: 1px; | |
| background: currentColor; | |
| transform: scaleX(0); | |
| transform-origin: left center; | |
| transition: transform var(--dd-t-base) var(--dd-ease); | |
| } | |
| @media (hover: hover) and (pointer: fine) { | |
| .docdoe-student-os .dd-link:hover::after { | |
| transform: scaleX(1); | |
| } | |
| } | |
| .docdoe-student-os .dd-link:focus-visible::after { | |
| transform: scaleX(1); | |
| } | |
| /* ββ Rows βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */ | |
| /* Rows replace cards for anything that repeats. The hover is a surface | |
| tint plus an arrow nudge β no lift, no shadow, no nested border. */ | |
| .docdoe-student-os .dd-row { | |
| position: relative; | |
| display: flex; | |
| align-items: center; | |
| gap: 12px; | |
| transition: background-color var(--dd-t-fast) var(--dd-ease); | |
| } | |
| @media (hover: hover) and (pointer: fine) { | |
| .docdoe-student-os .dd-row-interactive:hover { | |
| background: var(--dd-paper); | |
| } | |
| } | |
| /* ββ Meter ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */ | |
| /* Fills animate with scaleX so the value change never triggers layout. */ | |
| .docdoe-student-os .dd-meter { | |
| position: relative; | |
| height: 3px; | |
| width: 100%; | |
| overflow: hidden; | |
| border-radius: 999px; | |
| background: var(--dd-line); | |
| } | |
| .docdoe-student-os .dd-meter > i { | |
| position: absolute; | |
| inset: 0; | |
| display: block; | |
| border-radius: inherit; | |
| background: var(--dd-ink); | |
| transform-origin: left center; | |
| transform: scaleX(var(--dd-value, 0)); | |
| transition: transform var(--dd-t-settle) var(--dd-ease); | |
| } | |
| /* ββ Chips ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */ | |
| .docdoe-student-os .dd-chip { | |
| display: inline-flex; | |
| align-items: center; | |
| gap: 6px; | |
| border-radius: 999px; | |
| padding: 4px 9px; | |
| font-size: 11px; | |
| font-weight: 600; | |
| letter-spacing: 0.02em; | |
| line-height: 1; | |
| white-space: nowrap; | |
| } | |
| .docdoe-student-os .dd-chip-ink { | |
| background: var(--dd-ink); | |
| color: #fff; | |
| } | |
| .docdoe-student-os .dd-chip-quiet { | |
| background: var(--dd-sunk); | |
| color: var(--dd-ink-2); | |
| } | |
| .docdoe-student-os .dd-chip-outline { | |
| border: 1px solid var(--dd-line-strong); | |
| color: var(--dd-ink-2); | |
| } | |
| /* ββ Completion tick ββββββββββββββββββββββββββββββββββββββββββββββββ */ | |
| /* The ring draws itself when a task is completed. It is the only place a | |
| stroke animation appears, because it is the one state change a student | |
| performs deliberately and wants confirmed. */ | |
| .docdoe-student-os .dd-tick { | |
| display: grid; | |
| place-items: center; | |
| border-radius: 999px; | |
| border: 1.5px solid var(--dd-line-strong); | |
| color: transparent; | |
| transition: | |
| border-color var(--dd-t-base) var(--dd-ease), | |
| background-color var(--dd-t-base) var(--dd-ease), | |
| color var(--dd-t-base) var(--dd-ease), | |
| transform var(--dd-t-fast) var(--dd-ease); | |
| } | |
| @media (hover: hover) and (pointer: fine) { | |
| .docdoe-student-os button:hover > .dd-tick, | |
| .docdoe-student-os .dd-tick-host:hover .dd-tick { | |
| border-color: var(--dd-positive); | |
| transform: scale(1.06); | |
| } | |
| } | |
| .docdoe-student-os .dd-tick-done { | |
| border-color: var(--dd-positive); | |
| background: var(--dd-positive); | |
| color: #fff; | |
| } | |
| @keyframes dd-tick-pop { | |
| 0% { transform: scale(0.82); } | |
| 60% { transform: scale(1.08); } | |
| 100% { transform: scale(1); } | |
| } | |
| .docdoe-student-os .dd-tick-just-done { | |
| animation: dd-tick-pop 240ms var(--dd-ease); | |
| } | |
| /* ββ Fields βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */ | |
| .docdoe-student-os .dd-field { | |
| border-radius: var(--dd-r-lg); | |
| border: 1px solid var(--dd-line-strong); | |
| background: var(--dd-panel); | |
| transition: | |
| border-color var(--dd-t-base) var(--dd-ease), | |
| box-shadow var(--dd-t-base) var(--dd-ease); | |
| } | |
| .docdoe-student-os .dd-field:focus-within { | |
| border-color: rgb(23 23 22 / 0.42); | |
| box-shadow: 0 0 0 3px rgb(23 23 22 / 0.07); | |
| } | |
| /* ββ Board surface ββββββββββββββββββββββββββββββββββββββββββββββββββ */ | |
| /* The one dark surface in the product. It is a blackboard, so it gets a | |
| chalk hairline and a vignette rather than a card shadow, and the chalk | |
| hue is confined to rules inside this element. */ | |
| .docdoe-student-os .dd-board { | |
| position: relative; | |
| overflow: hidden; | |
| background: var(--dd-board); | |
| color: var(--dd-board-ink); | |
| border-radius: var(--dd-r-lg); | |
| } | |
| .docdoe-student-os .dd-board::after { | |
| content: ""; | |
| position: absolute; | |
| inset: 0; | |
| pointer-events: none; | |
| background: radial-gradient( | |
| 120% 90% at 88% 6%, | |
| rgb(234 208 140 / 0.07), | |
| transparent 62% | |
| ); | |
| } | |
| .docdoe-student-os .dd-chalk-rule { | |
| height: 1px; | |
| border: 0; | |
| background: linear-gradient( | |
| 90deg, | |
| rgb(234 208 140 / 0.5), | |
| rgb(234 208 140 / 0.1) 55%, | |
| transparent | |
| ); | |
| } | |
| /* ββ Reduced motion βββββββββββββββββββββββββββββββββββββββββββββββββ */ | |
| /* ββ Route reveal ββββββββββββββββββββββββββββββββββββββββββββββββββ */ | |
| /* One entrance per route, never per card and never scroll-triggered: the | |
| page arrives as a single block so a student re-entering a tab is not | |
| waiting on a cascade. Everything below it is state-transition motion. */ | |
| @keyframes dd-page-in { | |
| from { | |
| opacity: 0; | |
| transform: translate3d(0, 7px, 0); | |
| } | |
| to { | |
| opacity: 1; | |
| transform: translate3d(0, 0, 0); | |
| } | |
| } | |
| .docdoe-student-os .dd-page-in { | |
| animation: dd-page-in var(--dd-t-slow) var(--dd-ease) both; | |
| } | |
| /* A conversation entry is the one repeat element allowed to animate in: | |
| each message is a discrete arrival, not decoration. */ | |
| @keyframes dd-entry-in { | |
| from { | |
| opacity: 0; | |
| transform: translate3d(0, 9px, 0); | |
| } | |
| to { | |
| opacity: 1; | |
| transform: translate3d(0, 0, 0); | |
| } | |
| } | |
| .docdoe-student-os .dd-entry { | |
| animation: dd-entry-in 240ms var(--dd-ease) both; | |
| } | |
| /* ββ Status blocks βββββββββββββββββββββββββββββββββββββββββββββββββ */ | |
| /* Hue is evidence, never decoration. Each block states one fact about the | |
| student's work, so at most one appears per reading band. */ | |
| .docdoe-student-os .dd-status { | |
| display: flex; | |
| align-items: flex-start; | |
| gap: 10px; | |
| border-radius: var(--dd-r-md); | |
| border: 1px solid; | |
| padding: 11px 13px; | |
| font-size: 13px; | |
| line-height: 20px; | |
| } | |
| .docdoe-student-os .dd-status > svg { | |
| margin-top: 3px; | |
| flex-shrink: 0; | |
| } | |
| .docdoe-student-os .dd-status-positive { | |
| border-color: var(--dd-positive-line); | |
| background: var(--dd-positive-soft); | |
| color: var(--dd-positive); | |
| } | |
| .docdoe-student-os .dd-status-attention { | |
| border-color: var(--dd-attention-line); | |
| background: var(--dd-attention-soft); | |
| color: var(--dd-attention); | |
| } | |
| .docdoe-student-os .dd-status-critical { | |
| border-color: var(--dd-critical-line); | |
| background: var(--dd-critical-soft); | |
| color: var(--dd-critical); | |
| } | |
| /* ββ Quiet icon button βββββββββββββββββββββββββββββββββββββββββββββ */ | |
| /* Chrome controls sit at the edge of the reading band. They gain a surface | |
| on hover rather than a colour change, so they stay furniture. */ | |
| .docdoe-student-os .dd-icon-btn { | |
| display: grid; | |
| place-items: center; | |
| border-radius: var(--dd-r-md); | |
| color: var(--dd-muted); | |
| transition: | |
| background-color var(--dd-t-fast) var(--dd-ease), | |
| color var(--dd-t-fast) var(--dd-ease), | |
| transform var(--dd-t-fast) var(--dd-ease); | |
| } | |
| @media (hover: hover) and (pointer: fine) { | |
| .docdoe-student-os .dd-icon-btn:hover:not(:disabled) { | |
| background: var(--dd-sunk); | |
| color: var(--dd-ink); | |
| } | |
| } | |
| .docdoe-student-os .dd-icon-btn:active:not(:disabled) { | |
| transform: scale(0.94); | |
| } | |
| .docdoe-student-os .dd-icon-btn:disabled { | |
| opacity: 0.4; | |
| } | |
| /* ββ Rails βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */ | |
| /* Side rails are ruled lists on the sunken canvas β never a stack of | |
| cards, because a rail is navigation and cards imply content. */ | |
| .docdoe-student-os .dd-rail { | |
| display: flex; | |
| min-height: 0; | |
| flex-direction: column; | |
| } | |
| .docdoe-student-os .dd-rail-head { | |
| padding: 16px 16px 12px; | |
| } | |
| .docdoe-student-os .dd-rail-scroll { | |
| min-height: 0; | |
| flex: 1; | |
| overflow-y: auto; | |
| padding: 4px 8px; | |
| } | |
| .docdoe-student-os .dd-rail-item { | |
| display: flex; | |
| width: 100%; | |
| align-items: flex-start; | |
| gap: 10px; | |
| border-radius: var(--dd-r-md); | |
| padding: 9px 10px; | |
| text-align: left; | |
| transition: | |
| background-color var(--dd-t-fast) var(--dd-ease), | |
| color var(--dd-t-fast) var(--dd-ease); | |
| } | |
| @media (hover: hover) and (pointer: fine) { | |
| .docdoe-student-os .dd-rail-item:hover:not([data-active="true"]) { | |
| background: var(--dd-panel); | |
| } | |
| } | |
| .docdoe-student-os .dd-rail-item[data-active="true"] { | |
| background: var(--dd-ink); | |
| color: #fff; | |
| box-shadow: inset 0 0 0 1px rgb(255 255 255 / 0.1); | |
| } | |
| /* ββ Conversation ββββββββββββββββββββββββββββββββββββββββββββββββββ */ | |
| /* The student's own message is the only inverted block in the thread. The | |
| asymmetric corner is the tail: it points at the sender without an avatar | |
| bubble competing with the assistant's mark. */ | |
| .docdoe-student-os .dd-bubble-user { | |
| border-radius: 16px 16px 4px 16px; | |
| background: var(--dd-ink); | |
| color: #fff; | |
| padding: 11px 15px; | |
| font-size: 14px; | |
| line-height: 24px; | |
| box-shadow: inset 0 0 0 1px rgb(255 255 255 / 0.08); | |
| } | |
| /* Assistant sections are ruled, not boxed: a multi-part answer reads as one | |
| continuous document with an index in the margin. */ | |
| .docdoe-student-os .dd-answer-section { | |
| border-top: 1px solid var(--dd-line); | |
| padding: 16px 0; | |
| } | |
| .docdoe-student-os .dd-answer-section:last-of-type { | |
| border-bottom: 1px solid var(--dd-line); | |
| } | |
| /* ββ Prose βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */ | |
| /* Tutor output is markdown, so the reading measure and rhythm are set here | |
| rather than per call site. Without this every answer re-invents spacing. */ | |
| .docdoe-student-os .dd-prose { | |
| font-size: 14.5px; | |
| line-height: 26px; | |
| color: var(--dd-ink-2); | |
| } | |
| .docdoe-student-os .dd-prose > :first-child { | |
| margin-top: 0; | |
| } | |
| .docdoe-student-os .dd-prose > :last-child { | |
| margin-bottom: 0; | |
| } | |
| .docdoe-student-os .dd-prose p { | |
| margin-block: 0 12px; | |
| } | |
| .docdoe-student-os .dd-prose strong { | |
| font-weight: 600; | |
| color: var(--dd-ink); | |
| } | |
| .docdoe-student-os .dd-prose h1, | |
| .docdoe-student-os .dd-prose h2, | |
| .docdoe-student-os .dd-prose h3, | |
| .docdoe-student-os .dd-prose h4 { | |
| margin-block: 18px 8px; | |
| font-weight: 600; | |
| letter-spacing: -0.022em; | |
| color: var(--dd-ink); | |
| } | |
| .docdoe-student-os .dd-prose h3 { | |
| font-size: 15px; | |
| } | |
| .docdoe-student-os .dd-prose ul, | |
| .docdoe-student-os .dd-prose ol { | |
| margin-block: 12px; | |
| padding-left: 20px; | |
| } | |
| .docdoe-student-os .dd-prose ul { | |
| list-style: disc; | |
| } | |
| .docdoe-student-os .dd-prose ol { | |
| list-style: decimal; | |
| } | |
| .docdoe-student-os .dd-prose li { | |
| margin-block: 5px; | |
| } | |
| .docdoe-student-os .dd-prose li::marker { | |
| color: var(--dd-faint); | |
| } | |
| .docdoe-student-os .dd-prose code { | |
| border-radius: 4px; | |
| background: var(--dd-sunk); | |
| padding: 1px 5px; | |
| font-family: var(--font-mono), ui-monospace, monospace; | |
| font-size: 0.9em; | |
| } | |
| .docdoe-student-os .dd-prose pre { | |
| margin-block: 14px; | |
| overflow-x: auto; | |
| border-radius: var(--dd-r-md); | |
| background: var(--dd-sunk); | |
| padding: 12px 14px; | |
| } | |
| .docdoe-student-os .dd-prose pre code { | |
| background: none; | |
| padding: 0; | |
| } | |
| .docdoe-student-os .dd-prose blockquote { | |
| margin-block: 14px; | |
| border-left: 2px solid var(--dd-line-strong); | |
| padding-left: 14px; | |
| color: var(--dd-muted); | |
| } | |
| .docdoe-student-os .dd-prose a { | |
| color: var(--dd-ink); | |
| text-decoration: underline; | |
| text-decoration-color: var(--dd-line-strong); | |
| text-underline-offset: 3px; | |
| transition: text-decoration-color var(--dd-t-fast) var(--dd-ease); | |
| } | |
| @media (hover: hover) and (pointer: fine) { | |
| .docdoe-student-os .dd-prose a:hover { | |
| text-decoration-color: var(--dd-ink); | |
| } | |
| } | |
| .docdoe-student-os .dd-prose table { | |
| margin-block: 14px; | |
| width: 100%; | |
| border-collapse: collapse; | |
| font-size: 13.5px; | |
| } | |
| .docdoe-student-os .dd-prose th, | |
| .docdoe-student-os .dd-prose td { | |
| border-bottom: 1px solid var(--dd-line); | |
| padding: 7px 10px; | |
| text-align: left; | |
| } | |
| .docdoe-student-os .dd-prose th { | |
| font-weight: 600; | |
| color: var(--dd-ink); | |
| } | |
| .docdoe-student-os .dd-prose hr { | |
| margin-block: 18px; | |
| border: 0; | |
| border-top: 1px solid var(--dd-line); | |
| } | |
| /* ββ Small actions βββββββββββββββββββββββββββββββββββββββββββββββββ */ | |
| /* Secondary actions under an answer. Outlined and quiet so the primary | |
| reading path stays the answer itself. */ | |
| .docdoe-student-os .dd-action { | |
| display: inline-flex; | |
| height: 32px; | |
| align-items: center; | |
| gap: 6px; | |
| border-radius: var(--dd-r-sm); | |
| border: 1px solid var(--dd-line); | |
| background: transparent; | |
| padding-inline: 10px; | |
| font-size: 12px; | |
| font-weight: 500; | |
| color: var(--dd-muted); | |
| white-space: nowrap; | |
| transition: | |
| background-color var(--dd-t-fast) var(--dd-ease), | |
| border-color var(--dd-t-fast) var(--dd-ease), | |
| color var(--dd-t-fast) var(--dd-ease); | |
| } | |
| @media (hover: hover) and (pointer: fine) { | |
| .docdoe-student-os .dd-action:hover:not(:disabled) { | |
| background: var(--dd-sunk); | |
| border-color: var(--dd-line-strong); | |
| color: var(--dd-ink); | |
| } | |
| } | |
| .docdoe-student-os .dd-action:disabled { | |
| opacity: 0.45; | |
| cursor: not-allowed; | |
| } | |
| /* ββ Removable chip ββββββββββββββββββββββββββββββββββββββββββββββββ */ | |
| .docdoe-student-os .dd-chip-remove { | |
| display: inline-flex; | |
| max-width: 220px; | |
| align-items: center; | |
| gap: 6px; | |
| border-radius: var(--dd-r-sm); | |
| background: var(--dd-sunk); | |
| padding: 5px 8px; | |
| font-size: 12px; | |
| font-weight: 500; | |
| color: var(--dd-ink-2); | |
| transition: | |
| background-color var(--dd-t-fast) var(--dd-ease), | |
| color var(--dd-t-fast) var(--dd-ease); | |
| } | |
| @media (hover: hover) and (pointer: fine) { | |
| .docdoe-student-os .dd-chip-remove:hover { | |
| background: var(--dd-ink); | |
| color: #fff; | |
| } | |
| } | |
| .docdoe-student-os .dd-chip-remove > svg { | |
| flex-shrink: 0; | |
| opacity: 0.55; | |
| transition: opacity var(--dd-t-fast) var(--dd-ease); | |
| } | |
| .docdoe-student-os .dd-chip-remove:hover > svg { | |
| opacity: 1; | |
| } | |
| /* ββ Citation ββββββββββββββββββββββββββββββββββββββββββββββββββββββ */ | |
| /* Evidence rows. They must look like a source, not a button: a hairline | |
| border that only strengthens on intent. */ | |
| .docdoe-student-os .dd-cite { | |
| display: block; | |
| border-radius: var(--dd-r-md); | |
| border: 1px solid var(--dd-line); | |
| background: var(--dd-panel); | |
| padding: 10px 12px; | |
| transition: | |
| border-color var(--dd-t-fast) var(--dd-ease), | |
| background-color var(--dd-t-fast) var(--dd-ease); | |
| } | |
| @media (hover: hover) and (pointer: fine) { | |
| .docdoe-student-os .dd-cite:hover { | |
| border-color: var(--dd-line-strong); | |
| background: var(--dd-paper); | |
| } | |
| } | |
| /* ββ Route stepper βββββββββββββββββββββββββββββββββββββββββββββββββ */ | |
| /* A class is a sequence, so the steps get a real spine: one hairline | |
| connecting the nodes rather than 5 identical boxed rows. */ | |
| .docdoe-student-os .dd-stepper { | |
| position: relative; | |
| } | |
| .docdoe-student-os .dd-step { | |
| position: relative; | |
| display: flex; | |
| align-items: flex-start; | |
| gap: 12px; | |
| padding-block: 13px; | |
| } | |
| .docdoe-student-os .dd-step + .dd-step { | |
| border-top: 1px solid var(--dd-line); | |
| } | |
| .docdoe-student-os .dd-step-node { | |
| display: grid; | |
| place-items: center; | |
| flex-shrink: 0; | |
| border-radius: 999px; | |
| border: 1px solid var(--dd-line-strong); | |
| background: var(--dd-panel); | |
| color: var(--dd-faint); | |
| transition: | |
| background-color var(--dd-t-base) var(--dd-ease), | |
| border-color var(--dd-t-base) var(--dd-ease), | |
| color var(--dd-t-base) var(--dd-ease); | |
| } | |
| .docdoe-student-os .dd-step[data-current="true"] .dd-step-node { | |
| border-color: var(--dd-ink); | |
| background: var(--dd-ink); | |
| color: #fff; | |
| } | |
| /* ββ Hero spine ββββββββββββββββββββββββββββββββββββββββββββββββββββ */ | |
| /* The day's hero earns one piece of structure the rest of the page does | |
| not get: an ink edge that marks it as the first thing to read. */ | |
| .docdoe-student-os .dd-spine { | |
| position: relative; | |
| } | |
| .docdoe-student-os .dd-spine::before { | |
| content: ""; | |
| position: absolute; | |
| inset-block: 0; | |
| left: 0; | |
| width: 3px; | |
| background: var(--dd-ink); | |
| } | |
| /* ββ Board-detail strip ββββββββββββββββββββββββββββββββββββββββββββ */ | |
| /* Hairline metadata strip on the inverted hero. Uses paper translucency, | |
| never a chalk hue β chalk is reserved for actual board surfaces. */ | |
| .docdoe-student-os .dd-ink-rule { | |
| height: 1px; | |
| border: 0; | |
| background: linear-gradient( | |
| 90deg, | |
| rgb(255 255 255 / 0.22), | |
| rgb(255 255 255 / 0.05) 60%, | |
| transparent | |
| ); | |
| } | |
| @media (prefers-reduced-motion: reduce) { | |
| .docdoe-student-os .dd-tick-just-done, | |
| .docdoe-student-os .dd-arrow, | |
| .docdoe-student-os .dd-mark, | |
| .docdoe-student-os .dd-page-in, | |
| .docdoe-student-os .dd-entry { | |
| animation: none; | |
| transform: none; | |
| } | |
| .docdoe-student-os .dd-meter > i { | |
| transition: none; | |
| } | |
| .docdoe-student-os .dd-page-in, | |
| .docdoe-student-os .dd-entry { | |
| opacity: 1; | |
| } | |
| } | |