:root{--g-arrow-color: #1f2937;--g-bar-color: #fff;--g-bar-border: #fff;--g-tick-color-thick: #ededed;--g-tick-color: #f3f3f3;--g-actions-background: #f3f3f3;--g-border-color: #ebeff2;--g-text-muted: #7c7c7c;--g-text-light: #fff;--g-text-dark: #171717;--g-progress-color: #dbdbdb;--g-handle-color: #37352f;--g-weekend-label-color: #dcdce4;--g-expected-progress: #c4c4e9;--g-header-background: #fff;--g-row-color: #fdfdfd;--g-row-border-color: #c7c7c7;--g-today-highlight: #37352f;--g-popup-actions: #ebeff2;--g-weekend-highlight-color: #f7f7f7}html[data-theme=dark]{--g-arrow-color: #e5e5e5;--g-bar-color: #2a2a2a;--g-bar-border: #3a3a3a;--g-tick-color-thick: #1a1a1a;--g-tick-color: #0a0a0a;--g-actions-background: #1a1a1a;--g-border-color: #2a2a2a;--g-text-muted: #999999;--g-text-light: #ffffff;--g-text-dark: #f5f5f5;--g-progress-color: #4a4a4a;--g-handle-color: #d0d0d0;--g-weekend-label-color: #3a3a3a;--g-expected-progress: #5a5a5a;--g-header-background: #0a0a0a;--g-row-color: #141414;--g-row-border-color: #2a2a2a;--g-today-highlight: #999999;--g-popup-actions: #1a1a1a;--g-weekend-highlight-color: #0f0f0f}.gantt-container{line-height:14.5px;position:relative;overflow:auto;font-size:12px;height:var(--gv-grid-height);width:100%;border-radius:8px;isolation:isolate}.gantt-container .popup-wrapper{position:absolute;top:0;left:0;background:var(--g-header-background);box-shadow:0 10px 24px -3px #0003;padding:10px;border-radius:5px;width:max-content;z-index:1000}.gantt-container .popup-wrapper .title{margin-bottom:2px;color:var(--g-text-dark);font-size:.85rem;font-weight:650;line-height:15px}.gantt-container .popup-wrapper .subtitle{color:var(--g-text-dark);font-size:.8rem;margin-bottom:5px}.gantt-container .popup-wrapper .details{color:var(--g-text-muted);font-size:.7rem}.gantt-container .popup-wrapper .actions{margin-top:10px;margin-left:3px}.gantt-container .popup-wrapper .action-btn{border:none;padding:5px 8px;background-color:var(--g-popup-actions);border-right:1px solid var(--g-border-color)}.gantt-container .popup-wrapper .action-btn:hover{filter:brightness(97%)}.gantt-container .popup-wrapper .action-btn:first-child{border-top-left-radius:4px;border-bottom-left-radius:4px}.gantt-container .popup-wrapper .action-btn:last-child{border-right:none;border-top-right-radius:4px;border-bottom-right-radius:4px}.gantt-container .grid-header{height:calc(var(--gv-lower-header-height) + var(--gv-upper-header-height) + 10px);background-color:var(--g-header-background);position:sticky;top:0;left:0;border-bottom:1px solid var(--g-row-border-color);z-index:1000}.gantt-container .lower-text,.gantt-container .upper-text{text-anchor:middle}.gantt-container .upper-header{height:var(--gv-upper-header-height)}.gantt-container .lower-header{height:var(--gv-lower-header-height)}.gantt-container .lower-text{font-size:12px;position:absolute;width:calc(var(--gv-column-width) * .8);height:calc(var(--gv-lower-header-height) * .8);margin:0 calc(var(--gv-column-width) * .1);align-content:center;text-align:center;color:var(--g-text-muted)}.gantt-container .upper-text{position:absolute;width:fit-content;font-weight:500;font-size:14px;color:var(--g-text-dark);height:calc(var(--gv-lower-header-height) * .66)}.gantt-container .current-upper{position:sticky;left:0!important;padding-left:17px;background:var(--g-header-background)}.gantt-container .side-header{position:sticky;top:0;right:0;float:right;z-index:1000;line-height:20px;font-weight:400;width:max-content;margin-left:auto;padding-right:10px;padding-top:10px;background:var(--g-header-background);display:flex}.gantt-container .side-header *{transition-property:background-color;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s;background-color:var(--g-actions-background);border-radius:.5rem;border:none;padding:5px 8px;color:var(--g-text-dark);font-size:14px;letter-spacing:.02em;font-weight:420;box-sizing:content-box;margin-right:5px}.gantt-container .side-header *:last-child{margin-right:0}.gantt-container .side-header *:hover{filter:brightness(97.5%)}.gantt-container .side-header select{width:60px;padding-top:2px;padding-bottom:2px}.gantt-container .side-header select:focus{outline:none}.gantt-container .date-range-highlight{background-color:var(--g-progress-color);border-radius:12px;height:calc(var(--gv-lower-header-height) - 6px);top:calc(var(--gv-upper-header-height) + 5px);position:absolute}.gantt-container .current-highlight{position:absolute;background:var(--g-today-highlight);width:1px;z-index:999}.gantt-container .current-ball-highlight{position:absolute;background:var(--g-today-highlight);z-index:1001;border-radius:50%}.gantt-container .current-date-highlight{background:var(--g-today-highlight);color:var(--g-text-light);border-radius:5px}.gantt-container .holiday-label{position:absolute;top:0;left:0;opacity:0;z-index:1000;background:var(--g-weekend-label-color);border-radius:5px;padding:2px 5px}.gantt-container .holiday-label.show{opacity:100}.gantt-container .extras{position:sticky;left:0}.gantt-container .extras .adjust{position:absolute;left:8px;top:calc(var(--gv-grid-height) - 60px);background-color:var(--g-actions-background);color:var(--g-text-light);border:none;padding:8px;border-radius:3px}.gantt-container .hide{display:none}.gantt{user-select:none;-webkit-user-select:none;position:absolute}.gantt .grid-background{fill:none}.gantt .grid-row{fill:var(--g-row-color)}.gantt .row-line{stroke:var(--g-border-color)}.gantt .tick{stroke:var(--g-tick-color);stroke-width:.4}.gantt .tick.thick{stroke:var(--g-tick-color-thick);stroke-width:.7}.gantt .arrow{fill:none;stroke:var(--g-arrow-color);stroke-width:1.5}.gantt .bar-wrapper .bar{fill:var(--g-bar-color);stroke:var(--g-bar-border);stroke-width:0;transition:stroke-width .3s ease}.gantt .bar-progress{fill:var(--g-progress-color);border-radius:4px}.gantt .bar-expected-progress{fill:var(--g-expected-progress)}.gantt .bar-invalid{fill:transparent;stroke:var(--g-bar-border);stroke-width:1;stroke-dasharray:5}:is(.gantt .bar-invalid)~.bar-label{fill:var(--g-text-light)}.gantt .bar-label{fill:var(--g-text-dark);dominant-baseline:central;font-family:Helvetica;font-size:13px;font-weight:400}.gantt .bar-label.big{fill:var(--g-text-dark);text-anchor:start}.gantt .handle{fill:var(--g-handle-color);opacity:0;transition:opacity .3s ease}.gantt .handle.active,.gantt .handle.visible{cursor:ew-resize;opacity:1}.gantt .handle.progress{fill:var(--g-text-muted)}.gantt .bar-wrapper{cursor:pointer}.gantt .bar-wrapper .bar{outline:1px solid var(--g-row-border-color);border-radius:3px}.gantt .bar-wrapper:hover .bar{transition:transform .3s ease}.gantt .bar-wrapper:hover .date-range-highlight{display:block}.gantt .grid-column{fill:transparent;pointer-events:all}.gantt .grid-column:hover{fill:var(--g-weekend-highlight-color);transition:fill .1s ease}:root,:root[data-theme=light]{--color-primary: #1C1B1B;--color-primary-dark: #000000;--color-primary-light: #3A3838;--color-on-primary: #FFFFFF;--color-accent: #F9B91B;--color-accent-dark: #D49C12;--color-accent-soft: #FEF9EF;--color-bg: #FCF9F8;--color-surface: #FFFFFF;--color-surface-low: #F3F0EE;--color-surface-mid: #E8E4DE;--color-zebra: #F7F4F1;--color-text: #1C1B1B;--color-text-variant: #4C616C;--color-text-inverse: #FCF9F8;--color-text-muted: #9E9A94;--color-border: #E5E2E1;--color-border-strong: #D4D0CB;--color-moss: #2E7D32;--color-sky: #1565C0;--color-ember: #E65100;--color-rust: #BA1A1A;--color-error: #BA1A1A;--color-error-container: #FEF2F2;--aging-0: #2E7D32;--aging-30: #B45309;--aging-60: #E65100;--aging-90: #D03A2B;--aging-120: #BA1A1A;--font-tc: "Taipei Sans TC Beta", "Noto Sans TC", -apple-system, "PingFang TC", "Microsoft JhengHei", sans-serif;--font-mono: "DM Mono", "JetBrains Mono", "Consolas", "Roboto Mono", monospace;--font-display-en: "Archivo Black", var(--font-tc);--fs-headline-lg: 28px;--fs-headline-md: 20px;--fs-body-lg: 16px;--fs-body-md: 14px;--fs-label-sm: 12px;--row-standard: 48px;--row-dense: 40px;--gutter: 16px;--page-margin: 24px;--radius-sm: 2px;--radius: 4px;--radius-md: 6px;--radius-lg: 8px;--radius-xl: 12px;--radius-full: 9999px;--shadow-soft: 0 1px 3px rgba(28,27,27,.06), 0 4px 12px rgba(28,27,27,.04);--shadow-card: 0 1px 3px rgba(28,27,27,.07), 0 6px 18px rgba(28,27,27,.05);--warning-stripe: repeating-linear-gradient(45deg, #F9B91B 0 12px, #1C1B1B 12px 24px)}:root[data-theme=dark]{--color-primary: #FCF9F8;--color-primary-dark: #FFFFFF;--color-primary-light: #D4C4AC;--color-on-primary: #1C1B1B;--color-accent: #F9B91B;--color-accent-dark: #FFCA3F;--color-accent-soft: rgba(249,185,27,.12);--color-bg: #1C1B1B;--color-surface: #2D2B2B;--color-surface-low: #3A3838;--color-surface-mid: #454241;--color-zebra: #353333;--color-text: #FCF9F8;--color-text-variant: #D4C4AC;--color-text-inverse: #1C1B1B;--color-text-muted: #8A857E;--color-border: #3A3838;--color-border-strong: #4C4847;--color-moss: #6EE7B7;--color-sky: #93C5FD;--color-ember: #FFA94D;--color-rust: #FF6B6B;--color-error: #FF6B6B;--color-error-container: rgba(255,107,107,.12);--aging-0: #6EE7B7;--aging-30: #FFCA3F;--aging-60: #FFA94D;--aging-90: #FF8787;--aging-120: #FF6B6B;--shadow-soft: 0 1px 3px rgba(0,0,0,.4), 0 4px 12px rgba(0,0,0,.3);--shadow-card: 0 1px 3px rgba(0,0,0,.5), 0 8px 24px rgba(0,0,0,.4)}@font-face{font-family:Taipei Sans TC Beta;src:url(/fonts/TaipeiSansTCBeta-Light.woff2) format("woff2");font-weight:300;font-style:normal;font-display:swap}@font-face{font-family:Taipei Sans TC Beta;src:url(/fonts/TaipeiSansTCBeta-Regular.woff2) format("woff2");font-weight:400;font-style:normal;font-display:swap}@font-face{font-family:Taipei Sans TC Beta;src:url(/fonts/TaipeiSansTCBeta-Bold.woff2) format("woff2");font-weight:700;font-style:normal;font-display:swap}*,*:before,*:after{box-sizing:border-box}html,body,#root{margin:0;padding:0;height:100%;font-family:var(--font-tc);font-size:var(--fs-body-md);line-height:1.6;color:var(--color-text);background:var(--color-bg);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}body{transition:background-color .2s,color .2s}a{color:var(--color-primary);text-decoration:none}a:hover{text-decoration:underline}button{font-family:inherit;font-size:inherit;cursor:pointer}.mono,.num{font-family:var(--font-mono);font-variant-numeric:tabular-nums}.text-muted{color:var(--color-text-muted)}.text-variant{color:var(--color-text-variant)}.tb-page-header{display:flex;align-items:flex-end;justify-content:space-between;gap:16px;margin-bottom:20px;flex-wrap:wrap}.tb-page-eyebrow{font-family:var(--font-mono);font-size:10px;color:var(--color-text-muted);letter-spacing:.18em;text-transform:uppercase;margin-bottom:6px}.tb-page-title{font-family:var(--font-display-en);font-size:36px;letter-spacing:-.02em;color:var(--color-text);line-height:1.05;margin:0}.tb-page-title-accent{color:var(--color-accent)}.tb-page-actions{display:flex;gap:8px;align-items:center}.tb-btn{display:inline-flex;align-items:center;justify-content:center;gap:6px;height:36px;padding:0 14px;border-radius:var(--radius-md);border:1px solid transparent;font-size:13px;font-weight:600;font-family:inherit;cursor:pointer;white-space:nowrap;transition:background-color .15s,color .15s,border-color .15s,transform .1s}.tb-btn:hover{transform:translateY(-1px)}.tb-btn:active{transform:translateY(0)}.tb-btn:disabled{opacity:.5;cursor:not-allowed;transform:none}.tb-btn.primary{background:var(--color-accent);color:#1c1b1b}.tb-btn.primary:hover{background:var(--color-accent-dark)}.tb-btn.outline{background:transparent;color:var(--color-text);border-color:var(--color-border-strong)}.tb-btn.outline:hover{background:var(--color-surface-low)}.tb-btn.ghost{background:transparent;color:var(--color-text-variant)}.tb-btn.ghost:hover{background:var(--color-surface-low);color:var(--color-text)}.tb-btn.danger{background:transparent;color:var(--color-rust);border-color:var(--color-rust)}.tb-btn.danger:hover{background:var(--color-error-container)}.tb-btn.sm{height:28px;padding:0 10px;font-size:12px}.tb-input,.tb-select,.tb-textarea{height:36px;padding:0 10px;border:1px solid var(--color-border-strong);border-radius:var(--radius-md);background:var(--color-surface);color:var(--color-text);font-family:inherit;font-size:13px;outline:none;min-width:0;transition:border-color .15s,box-shadow .15s}.tb-textarea{height:auto;padding:8px 10px;resize:vertical}.tb-input:focus,.tb-select:focus,.tb-textarea:focus{border-color:var(--color-accent);box-shadow:0 0 0 3px var(--color-accent-soft)}.tb-field{display:flex;flex-direction:column;gap:4px;min-width:0}.tb-field-label{font-family:var(--font-mono);font-size:10px;color:var(--color-text-muted);letter-spacing:.12em;text-transform:uppercase}.tb-filter-bar{display:flex;align-items:center;gap:8px;padding:10px 12px;background:var(--color-surface);border:1px solid var(--color-border);border-radius:10px;margin-bottom:16px;flex-wrap:wrap;box-shadow:var(--shadow-soft)}.tb-filter-label{font-family:var(--font-mono);font-size:10px;color:var(--color-text-muted);letter-spacing:.12em;text-transform:uppercase;margin-right:4px}.tb-chip{display:inline-flex;align-items:center;gap:5px;padding:4px 10px;border-radius:999px;font-size:11px;font-weight:500;border:1px solid var(--color-border-strong);background:var(--color-surface-low);color:var(--color-text-variant);cursor:pointer;white-space:nowrap;font-family:inherit;transition:background-color .15s,color .15s,border-color .15s}.tb-chip:hover{background:var(--color-surface-mid);color:var(--color-text)}.tb-chip.active{background:var(--color-accent);color:#1c1b1b;border-color:var(--color-accent);font-weight:700}.tb-card{background:var(--color-surface);border:1px solid var(--color-border);border-radius:var(--radius-xl);box-shadow:var(--shadow-soft);overflow:hidden}.tb-card-head{padding:12px 16px;border-bottom:1px solid var(--color-border);display:flex;align-items:center;gap:10px;background:var(--color-surface-low)}.tb-card-title{font-family:var(--font-display-en);font-size:13px;color:var(--color-text);letter-spacing:-.01em}.tb-card-body{padding:16px}.tb-card-spacer{flex:1}.tb-table{width:100%;border-collapse:collapse;font-size:13px}.tb-table th{text-align:left;padding:10px 12px;font-family:var(--font-mono);font-size:10px;font-weight:500;color:var(--color-text-muted);letter-spacing:.1em;text-transform:uppercase;border-bottom:1px solid var(--color-border-strong);background:var(--color-surface-low);position:sticky;top:0;z-index:1;white-space:nowrap}.tb-table td{padding:10px 12px;border-bottom:1px solid var(--color-border);color:var(--color-text);vertical-align:middle}.tb-table tbody tr{transition:background-color .15s}.tb-table tbody tr:hover{background:var(--color-surface-low)}.tb-table tbody tr.clickable{cursor:pointer}.tb-table td.num,.tb-table th.num{text-align:right}.tb-status{display:inline-flex;align-items:center;gap:5px;padding:2px 9px;border-radius:999px;font-size:11px;font-weight:600;white-space:nowrap;border:1px solid transparent}.tb-status .dot{width:6px;height:6px;border-radius:50%;background:currentColor}.tb-status.draft{color:var(--color-text-variant);background:var(--color-surface-low);border-color:var(--color-border-strong)}.tb-status.active{color:var(--color-sky);background:color-mix(in srgb,var(--color-sky) 12%,transparent)}.tb-status.closed{color:var(--color-moss);background:color-mix(in srgb,var(--color-moss) 12%,transparent)}.tb-status.archived{color:var(--color-text-muted);background:var(--color-surface-low)}.tb-aging{display:inline-flex;align-items:center;padding:2px 8px;border-radius:var(--radius);font-family:var(--font-mono);font-size:11px;font-weight:500;white-space:nowrap}.tb-aging.b0{color:var(--aging-0);background:color-mix(in srgb,var(--aging-0) 12%,transparent)}.tb-aging.b30{color:var(--aging-30);background:color-mix(in srgb,var(--aging-30) 12%,transparent)}.tb-aging.b60{color:var(--aging-60);background:color-mix(in srgb,var(--aging-60) 14%,transparent)}.tb-aging.b90{color:var(--aging-90);background:color-mix(in srgb,var(--aging-90) 15%,transparent)}.tb-aging.b120{color:#fff;background:var(--aging-120);position:relative}:root[data-theme=dark] .tb-aging.b120{color:#1c1b1b}.tb-stages{display:flex;gap:4px;align-items:stretch}.tb-stage{flex:1;padding:8px 12px;border-radius:var(--radius-md);background:var(--color-surface-low);border:1px solid var(--color-border);color:var(--color-text-muted);font-size:11px;font-weight:600;text-align:center;position:relative;overflow:hidden}.tb-stage .en{display:block;font-family:var(--font-mono);font-size:9px;letter-spacing:.14em;text-transform:uppercase;opacity:.7}.tb-stage.done{background:var(--color-accent-soft);border-color:var(--color-accent);color:var(--color-text)}.tb-stage.current{background:var(--color-accent);border-color:var(--color-accent);color:#1c1b1b}.tb-stage.current:before{content:"";position:absolute;left:0;right:0;top:0;height:3px;background:var(--warning-stripe)}.tb-kpi{background:var(--color-surface);border:1px solid var(--color-border);border-radius:var(--radius-xl);padding:14px 16px;box-shadow:var(--shadow-soft);border-top:3px solid var(--color-border-strong)}.tb-kpi .kpi-label{font-family:var(--font-mono);font-size:10px;color:var(--color-text-muted);letter-spacing:.14em;text-transform:uppercase}.tb-kpi .kpi-value{font-family:var(--font-mono);font-size:26px;font-weight:500;color:var(--color-text);margin-top:4px;line-height:1.1;font-variant-numeric:tabular-nums}.tb-kpi .kpi-sub{font-size:11px;color:var(--color-text-variant);margin-top:2px}.tb-sb-item{display:flex;align-items:center;gap:11px;padding:9px 12px;margin-bottom:2px;border-radius:6px;color:var(--color-text-variant);font-size:13px;font-weight:500;cursor:pointer;position:relative;transition:background-color .15s,color .15s;text-decoration:none}.tb-sb-item:hover{background:var(--color-surface-low);color:var(--color-text);text-decoration:none}.tb-sb-item.active{background:var(--color-accent-soft);color:var(--color-accent);font-weight:600}.tb-sb-item .tb-sb-rail{position:absolute;left:-8px;top:8px;bottom:8px;width:3px;background:transparent;border-radius:2px;transition:background-color .15s}.tb-sb-item.active .tb-sb-rail{background:var(--color-accent)}.tb-sb-item svg{flex-shrink:0}.theme-toggle{width:36px;height:36px;background:transparent;border:1px solid var(--color-border);border-radius:var(--radius);color:var(--color-text-variant);cursor:pointer;display:inline-flex;align-items:center;justify-content:center;transition:background .12s,color .12s,border-color .12s;flex-shrink:0}.theme-toggle:hover{background:var(--color-surface-low);color:var(--color-text);border-color:var(--color-border-strong)}.theme-toggle:focus-visible{outline:none;box-shadow:0 0 0 3px var(--color-accent-soft)}.tb-modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:50;background:#00000073;display:flex;align-items:center;justify-content:center;padding:24px 16px;overflow-y:auto}.tb-modal{background:var(--color-surface);border:1px solid var(--color-border);border-radius:16px;box-shadow:var(--shadow-card);width:100%;max-width:560px;max-height:calc(100vh - 48px);display:flex;flex-direction:column}.tb-modal-head,.tb-modal-foot{flex-shrink:0}.tb-modal-head{padding:14px 18px;border-bottom:1px solid var(--color-border);display:flex;align-items:center;gap:10px}.tb-modal-title{font-family:var(--font-display-en);font-size:15px;color:var(--color-text);flex:1}.tb-modal-body{padding:18px;overflow-y:auto;min-height:0}.tb-modal-foot{padding:12px 18px;border-top:1px solid var(--color-border);display:flex;justify-content:flex-end;gap:8px}.tb-banner{padding:8px 16px;font-size:var(--fs-label-sm);text-align:center;border-bottom:1px solid var(--color-accent);background:var(--color-accent-soft);color:var(--color-text)}.tb-banner.error{background:var(--color-error-container);border-color:var(--color-error);color:var(--color-error)}.gantt-container{border-radius:var(--radius-lg);border:1px solid var(--color-border)}.gantt .grid-background,.gantt .grid-row{fill:var(--color-surface)}.gantt .grid-row:nth-child(2n){fill:var(--color-zebra)}.gantt .row-line,.gantt .tick{stroke:var(--color-border)}.gantt .today-highlight{fill:var(--color-accent-soft);opacity:.6}.gantt .bar{fill:var(--color-surface-mid);stroke:var(--color-border-strong)}.gantt .bar-progress{fill:var(--color-accent)}.gantt .bar-label{fill:var(--color-text);font-family:var(--font-tc);font-size:11px}.gantt .bar-label.big{fill:var(--color-text)}.gantt .lower-text,.gantt .upper-text{fill:var(--color-text-variant);font-family:var(--font-mono)}.gantt .arrow{stroke:var(--color-text-muted)}.gantt-container .popup-wrapper{background:var(--color-surface);color:var(--color-text);border:1px solid var(--color-border-strong);border-radius:var(--radius-md);box-shadow:var(--shadow-card)}@keyframes tb-fade-up{0%{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}.tb-fade-up{animation:tb-fade-up .35s ease both}
