地方服務成果地圖|台北市議員 曾獻瑩
:root{
--navy:#0B1F3A;
--blue:#2F80ED;
--blue-bg:#EAF2FE;
--yellow:#FBD419;
--bg:#F5F8FC;
--gray:#8493A8;
--text2:#4A5A72;
--border:#EDF1F7;
--border2:#E4ECF7;
--green:#0F9D58;
--green-bg:#E6F7EE;
--amber:#8A6A00;
--amber-bg:#FFF6D8;
}
*{box-sizing:border-box;}
body{margin:0;background:#fff;color:var(--navy);font-family:'Noto Sans TC','Inter',sans-serif;}
::selection{background:var(--blue);color:#fff;}
img{max-width:100%;display:block;}
button{font-family:inherit;}
.wsc-wrap{max-width:1440px;margin:0 auto;background:#fff;}
/* NAV */
.wsc-nav{height:76px;display:flex;align-items:center;justify-content:space-between;padding:0 64px;border-bottom:1px solid var(--border);}
.wsc-nav-brand{display:flex;align-items:center;gap:12px;}
.wsc-logo{width:36px;height:36px;border-radius:10px;background:var(--blue);display:flex;align-items:center;justify-content:center;color:#fff;font-weight:800;font-size:16px;flex-shrink:0;}
.wsc-nav-title{font-size:15px;font-weight:700;letter-spacing:.3px;white-space:nowrap;}
.wsc-nav-links{display:flex;gap:40px;font-size:14px;font-weight:500;color:var(--text2);}
.wsc-nav-cta{padding:10px 22px;border-radius:999px;background:var(--navy);color:#fff;font-size:14px;font-weight:600;white-space:nowrap;cursor:pointer;border:none;}
.wsc-nav-toggle{display:none;background:none;border:none;cursor:pointer;padding:8px;}
.wsc-nav-toggle span{display:block;width:24px;height:2px;background:var(--navy);margin:5px 0;border-radius:2px;}
/* HERO */
.wsc-hero{position:relative;overflow:hidden;background:linear-gradient(180deg,#0B1F3A 0%,#123058 50%,#1E4C86 100%);min-height:460px;}
.wsc-hero-frame{position:absolute;inset:14px;border:2px dashed rgba(255,255,255,.25);border-radius:16px;overflow:hidden;}
.wsc-hero-photo{width:100%;height:100%;object-fit:cover;object-position:70% 20%;opacity:.9;}
.wsc-hero-overlay1{position:absolute;inset:0;background:linear-gradient(90deg, rgba(11,31,58,.88) 0%, rgba(11,31,58,.62) 38%, rgba(11,31,58,.15) 62%, rgba(11,31,58,.05) 100%);pointer-events:none;}
.wsc-hero-overlay2{position:absolute;inset:0;background:linear-gradient(180deg, rgba(11,31,58,.25) 0%, rgba(11,31,58,0) 30%, rgba(11,31,58,0) 70%, rgba(11,31,58,.35) 100%);pointer-events:none;}
.wsc-hero-content{position:relative;padding:88px 64px 64px;max-width:640px;}
.wsc-hero-eyebrow{font-size:14px;font-weight:700;color:var(--yellow);letter-spacing:1px;margin-bottom:20px;}
.wsc-hero-title{font-size:52px;font-weight:900;line-height:1.25;letter-spacing:.5px;color:#fff;margin:0;}
.wsc-hero-desc{font-size:18px;color:rgba(255,255,255,.9);margin-top:22px;line-height:1.8;}
/* MAP SECTION */
.wsc-section{padding:0 64px 32px;}
.wsc-section-title{font-size:19px;font-weight:800;margin-bottom:6px;}
.wsc-section-sub{font-size:13.5px;color:var(--gray);margin-bottom:20px;}
.wsc-map-desktop{position:relative;width:100%;aspect-ratio:1670/955;border-radius:24px;overflow:hidden;box-shadow:0 8px 28px rgba(11,31,58,.14);}
.wsc-map-desktop img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;pointer-events:none;}
.wsc-node-btn{position:absolute;transform:translate(-50%,-50%);display:flex;flex-direction:column;align-items:center;gap:6px;background:none;border:none;padding:0;cursor:pointer;z-index:1;}
.wsc-node-btn:hover{transform:translate(-50%,-50%) scale(1.07);}
.wsc-node-btn.active{z-index:2;}
.wsc-node-dot{width:16px;height:16px;border-radius:50%;background:var(--blue);box-shadow:0 0 0 6px rgba(47,128,237,.3),0 2px 6px rgba(11,31,58,.35);border:2px solid #fff;}
.wsc-node-btn.active .wsc-node-dot{background:var(--yellow);box-shadow:0 0 0 6px rgba(251,212,25,.35),0 2px 6px rgba(11,31,58,.35);}
.wsc-node-label{font-size:12.5px;font-weight:700;color:var(--navy);background:#fff;padding:5px 12px;border-radius:999px;box-shadow:0 3px 10px rgba(11,31,58,.18);white-space:nowrap;}
.wsc-node-btn.active .wsc-node-label{background:var(--yellow);}
.wsc-map-mobile{display:none;}
.wsc-tabs{display:flex;gap:8px;overflow-x:auto;padding:4px 0 14px;-webkit-overflow-scrolling:touch;}
.wsc-tab{flex-shrink:0;padding:8px 16px;border-radius:999px;font-size:12.5px;font-weight:700;white-space:nowrap;cursor:pointer;background:#fff;color:var(--navy);border:1px solid var(--border2);}
.wsc-tab.active{background:var(--blue);color:#fff;border-color:var(--blue);}
.wsc-mmap-wrap{position:relative;border-radius:20px;overflow:hidden;box-shadow:0 6px 20px rgba(11,31,58,.14);aspect-ratio:864/1636;width:100%;}
.wsc-mmap-wrap img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;pointer-events:none;}
.wsc-mnode-btn{position:absolute;transform:translate(-50%,-50%);background:none;border:none;padding:8px;cursor:pointer;z-index:1;}
.wsc-mnode-btn.active{z-index:2;}
/* PANEL */
.wsc-panel{margin-top:24px;border:1px solid var(--border2);border-radius:22px;padding:32px;background:#FAFCFF;}
.wsc-panel-name{font-size:20px;font-weight:800;margin-bottom:8px;}
.wsc-panel-scenario{font-size:14px;color:var(--text2);line-height:1.8;margin-bottom:14px;}
.wsc-chips{display:flex;flex-wrap:wrap;gap:8px;}
.wsc-chip{font-size:12.5px;color:var(--blue);background:var(--blue-bg);padding:6px 12px;border-radius:999px;font-weight:600;}
.wsc-panel-subhead{font-size:15px;font-weight:800;margin-bottom:14px;border-top:1px solid var(--border);padding-top:20px;color:var(--text2);}
.wsc-cases{display:flex;flex-direction:column;gap:10px;}
.wsc-case{border:1px solid var(--border);border-radius:14px;background:#fff;overflow:hidden;}
.wsc-case-head{padding:14px 18px;cursor:pointer;display:flex;align-items:center;gap:14px;}
.wsc-case-date{font-size:12px;color:var(--gray);white-space:nowrap;}
.wsc-case-tag{font-size:11px;font-weight:700;padding:4px 10px;border-radius:999px;white-space:nowrap;}
.wsc-case-title{font-size:13.5px;font-weight:700;flex:1;}
.wsc-case-toggle{display:flex;align-items:center;gap:4px;font-size:12px;color:var(--blue);font-weight:700;white-space:nowrap;}
.wsc-case-toggle svg{transition:transform .2s;}
.wsc-case.expanded .wsc-case-toggle svg{transform:rotate(90deg);}
.wsc-case-body{display:none;border-top:1px solid #F1F5FA;padding:14px 18px;background:#FAFCFF;gap:14px;align-items:flex-start;}
.wsc-case.expanded .wsc-case-body{display:flex;}
.wsc-case-thumb{width:96px;height:96px;border-radius:10px;background:var(--blue-bg) repeating-linear-gradient(45deg, rgba(11,31,58,.08) 0 2px, transparent 2px 10px);flex-shrink:0;}
.wsc-case-detail{flex:1;display:flex;flex-direction:column;gap:6px;font-size:12.5px;color:var(--text2);line-height:1.7;}
.wsc-case-detail b{font-weight:700;}
.wsc-case-updated{font-size:11px;color:var(--gray);}
.wsc-previews{display:grid;grid-template-columns:repeat(2,1fr);gap:14px;margin-top:14px;}
.wsc-preview{border:1px solid var(--border);border-radius:14px;padding:14px 16px;background:#fff;display:flex;flex-direction:column;gap:8px;}
.wsc-badge{font-size:11px;font-weight:700;padding:5px 12px;border-radius:999px;width:fit-content;}
.wsc-preview-title{font-size:13.5px;font-weight:700;}
.wsc-panel-cta{margin-top:24px;padding-top:20px;border-top:1px solid var(--border);display:flex;align-items:center;justify-content:space-between;gap:20px;flex-wrap:wrap;}
.wsc-panel-cta-text{font-size:14.5px;font-weight:700;}
.wsc-btn-yellow{padding:12px 22px;border-radius:12px;background:var(--yellow);color:var(--navy);font-size:14px;font-weight:700;cursor:pointer;white-space:nowrap;border:none;text-align:center;}
.status-done{background:var(--green-bg);color:var(--green);}
.status-track{background:var(--amber-bg);color:var(--amber);}
.status-coord{background:var(--blue-bg);color:var(--blue);}
/* HIGHLIGHTS */
.wsc-hl-head{display:flex;align-items:flex-end;justify-content:space-between;margin-bottom:24px;gap:20px;flex-wrap:wrap;}
.wsc-hl-title{font-size:24px;font-weight:800;margin-bottom:8px;}
.wsc-hl-sub{font-size:14px;color:var(--gray);max-width:640px;line-height:1.8;}
.wsc-hl-nav{display:flex;gap:10px;}
.wsc-hl-arrow{width:40px;height:40px;border-radius:50%;border:1px solid var(--border2);display:flex;align-items:center;justify-content:center;cursor:pointer;background:#fff;flex-shrink:0;}
.wsc-hl-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:24px;}
.wsc-hl-card{border:1px solid var(--border);border-radius:20px;overflow:hidden;box-shadow:0 2px 12px rgba(11,31,58,.04);display:flex;flex-direction:column;}
.wsc-hl-card.hidden{display:none;}
.wsc-hl-img{height:140px;background:var(--blue-bg) repeating-linear-gradient(45deg, rgba(11,31,58,.06) 0 2px, transparent 2px 14px);position:relative;}
.wsc-hl-placeholder{position:absolute;bottom:10px;left:12px;font-size:10.5px;font-family:monospace;color:var(--navy);background:rgba(255,255,255,.85);padding:3px 7px;border-radius:6px;}
.wsc-hl-status{position:absolute;top:10px;left:12px;font-size:11px;font-weight:700;padding:5px 12px;border-radius:999px;}
.wsc-hl-track{position:absolute;top:10px;right:12px;font-size:11px;font-weight:700;color:#fff;background:var(--navy);padding:4px 10px;border-radius:999px;}
.wsc-hl-body{padding:18px;display:flex;flex-direction:column;gap:10px;flex:1;}
.wsc-hl-tag{font-size:11px;font-weight:700;color:var(--blue);}
.wsc-hl-name{font-size:14.5px;font-weight:800;line-height:1.5;}
.wsc-hl-facts{display:flex;flex-direction:column;gap:6px;font-size:12px;color:var(--text2);line-height:1.7;}
.wsc-hl-facts b{color:var(--blue);font-weight:700;}
.wsc-dots{display:flex;justify-content:center;gap:8px;margin-top:24px;}
.wsc-dot{width:8px;height:8px;border-radius:50%;cursor:pointer;background:#D8E2F0;border:none;padding:0;}
.wsc-dot.active{background:var(--blue);}
/* PROCESS */
.wsc-process-box{border-radius:24px;padding:44px 48px;background:linear-gradient(160deg,#F3F8FF 0%,#EAF1FB 55%,#F5F8FC 100%);}
.wsc-process-title{font-size:22px;font-weight:800;margin-bottom:10px;}
.wsc-process-sub{font-size:14px;color:var(--text2);line-height:1.8;margin-bottom:40px;max-width:760px;}
.wsc-steps{position:relative;display:flex;justify-content:space-between;align-items:flex-start;flex-wrap:wrap;gap:20px;}
.wsc-steps-line{position:absolute;top:26px;left:5%;right:5%;height:2px;background:repeating-linear-gradient(90deg,#C7D8F2 0 8px,transparent 8px 14px);}
.wsc-step{position:relative;flex:1;min-width:130px;display:flex;flex-direction:column;align-items:center;text-align:center;padding:0 10px;}
.wsc-step-dot{position:relative;z-index:1;width:52px;height:52px;border-radius:50%;background:#fff;border:2px solid var(--blue);display:flex;align-items:center;justify-content:center;margin-bottom:16px;box-shadow:0 4px 12px rgba(11,31,58,.08);}
.wsc-step.is-last .wsc-step-dot{border-color:var(--yellow);}
.wsc-step-card{background:#fff;border-radius:16px;padding:18px 16px;box-shadow:0 4px 16px rgba(11,31,58,.05);width:100%;}
.wsc-step-num{font-size:12px;font-weight:800;color:var(--blue);letter-spacing:1px;}
.wsc-step.is-last .wsc-step-num{color:var(--amber);}
.wsc-step-label{font-size:14.5px;font-weight:800;margin:8px 0 6px;}
.wsc-step-desc{font-size:12px;color:var(--gray);line-height:1.7;}
/* MORE LINKS */
.wsc-more-title{font-size:20px;font-weight:800;margin-bottom:24px;}
.wsc-more-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:24px;}
.wsc-more-card{border:1px solid var(--border);border-radius:20px;padding:26px;display:flex;flex-direction:column;gap:16px;box-shadow:0 2px 12px rgba(11,31,58,.03);}
.wsc-more-name{font-size:16px;font-weight:800;}
.wsc-more-desc{font-size:13px;color:var(--gray);line-height:1.8;flex:1;}
.wsc-more-btn{align-self:flex-start;padding:12px 22px;border-radius:12px;font-size:14px;font-weight:700;cursor:pointer;border:none;}
.btn-dark{background:var(--navy);color:#fff;}
.btn-accent{background:var(--yellow);color:var(--navy);}
/* FOOTER */
.wsc-footer{padding:28px 64px;border-top:1px solid var(--border);display:flex;justify-content:space-between;font-size:13px;color:var(--gray);flex-wrap:wrap;gap:8px;}
/* RESPONSIVE */
@media (max-width:900px){
.wsc-nav{padding:0 20px;}
.wsc-nav-links{display:none;}
.wsc-nav-toggle{display:block;}
.wsc-nav-cta{display:none;}
.wsc-hero-content{padding:56px 24px 40px;max-width:100%;}
.wsc-hero-title{font-size:32px;}
.wsc-hero-desc{font-size:14.5px;max-width:320px;}
.wsc-hero{min-height:340px;}
.wsc-section{padding:0 20px 24px;}
.wsc-map-desktop{display:none;}
.wsc-map-mobile{display:block;}
.wsc-panel{padding:20px;border-radius:18px;}
.wsc-previews{grid-template-columns:1fr;}
.wsc-panel-cta{flex-direction:column;align-items:stretch;}
.wsc-btn-yellow{text-align:center;}
.wsc-hl-grid{grid-template-columns:1fr;}
.wsc-hl-title{font-size:19px;}
.wsc-process-box{padding:28px 20px;}
.wsc-steps{flex-direction:column;align-items:stretch;}
.wsc-steps-line{display:none;}
.wsc-step{flex-direction:row;text-align:left;align-items:center;gap:14px;padding:0;}
.wsc-step-dot{margin-bottom:0;flex-shrink:0;}
.wsc-more-grid{grid-template-columns:1fr;}
.wsc-footer{padding:24px 20px;flex-direction:column;}
}
台北市議員 曾獻瑩|大安文山
地方服務成果
居民反映的問題,獻瑩一件件接住、協調、追蹤,讓大安文山的改變真正落地。
點進你熟悉的生活圈,看看獻瑩追過哪些問題
點擊地圖上的生活圈節點,下方會展開對應的服務紀錄。
看得見的代表成果:獻瑩怎麼追到改變
從眾多地方服務中,整理出最有感、最能看見獻瑩努力的改善案例。
一件地方問題,獻瑩怎麼追到有進度?
從居民反映到局處協調,重點不是收件,而是把問題送到對的位置、追到有回應。
02
到現場看
獻瑩團隊會勘、拍照、確認問題位置與影響
05
回報居民
獻瑩團隊把處理進度回報給居民與社區
想更了解獻瑩做了什麼?
看問政成績
從地方服務到議會監督,看獻瑩如何把問題追到底。
政治獻金支持獻瑩
支持獻瑩繼續把地方問題追到底,讓服務不中斷、監督不中斷。
回首頁
認識獻瑩的理念、最新消息與服務資訊。
(function(){
// ---------- DATA ----------
const circlesData = [
{ key:"jm", name:"景美生活圈", scenario:"市場、學校、巷弄與每天經過的路",
chips:["環境清潔","道路修繕","市場周邊安全"],
posDesktop:{top:68,left:14}, posMobile:{top:60,left:20},
cases:[
{ status:"已改善", statusKey:"done", date:"2024/05/22", title:"福興路水溝清理",
process:"獻瑩團隊接獲居民反映後,協調相關單位到場處理,並追蹤後續維護。",
result:"完成清理並列入後續環境維護追蹤。",
impact:"居民不用再每天經過髒亂、積水的巷口,巷弄生活品質更穩定。" },
{ status:"持續追蹤", statusKey:"track", date:"2024/05/20", title:"新光路一段道路擁塞改善",
process:"獻瑩團隊接獲通勤族反映後,持續與交通局協調號誌與動線調整方案。",
result:"已完成初步調整,持續觀察成效。",
impact:"上下班時段回堵情形略有緩解,通勤族反映有感。" },
{ status:"已改善", statusKey:"done", date:"2024/04/30", title:"景美市場周邊機車停放整理",
process:"獻瑩團隊接獲攤商反映後,協調停管處增設停車格線並加強巡查。",
result:"周邊動線恢復順暢,攤商反映改善明顯。",
impact:"市場出入更安全,買菜、擺攤都不再被機車擋路。" },
{ status:"協調中", statusKey:"coord", date:"2024/04/12", title:"景美國小周邊人行道改善",
process:"獻瑩團隊接獲家長反映後,正協調工務局評估人行道拓寬與標線調整。",
result:"評估中,將提出改善方案。",
impact:"未來接送孩子的動線將更安全,家長不必再提心吊膽。" },
] },
{ key:"mz", name:"木柵生活圈", scenario:"從市場到社區公園,讓生活動線更順",
chips:["綠美化","公園設施","道路平整"],
posDesktop:{top:32,left:78}, posMobile:{top:22,left:24},
cases:[
{ status:"已改善", statusKey:"done", date:"2024/03/18", title:"木柵里國有土地綠美化案",
process:"獻瑩團隊協調財政部國產署與公園處,推動閒置地綠美化改造。",
result:"閒置地變成社區可用的休憩綠地。",
impact:"居民多了一處可散步、休憩的社區綠地,環境死角也消失了。" },
{ status:"協調中", statusKey:"coord", date:"2024/02/25", title:"木柵公園兒童遊具汰換",
process:"獻瑩團隊接獲家長反映後,協調公園處進行安全檢測並編列汰換預算。",
result:"已列入年度汰換計畫,等待施作。",
impact:"孩子未來遊玩會更安全,家長也能少一分擔心。" },
] },
{ key:"wf", name:"萬芳生活圈", scenario:"醫院、捷運與社區生活圈的日常改善",
chips:["交通安全","醫療周邊動線","公共設施"],
posDesktop:{top:66,left:84}, posMobile:{top:68,left:80},
cases:[
{ status:"持續追蹤", statusKey:"track", date:"2024/05/02", title:"萬芳醫院周邊人行道改善",
process:"獻瑩團隊接獲就醫民眾反映後,協調工務局現勘評估拓寬與無障礙改善。",
result:"設計方案已提出,等待排入施作期程。",
impact:"未來就醫民眾與輪椅使用者通行將更順暢、更安全。" },
{ status:"已改善", statusKey:"done", date:"2024/03/09", title:"萬芳社區增設路燈",
process:"獻瑩團隊接獲居民反映後,協調工務局養護處於重點路段增設路燈。",
result:"完成增設,夜間通行安全感提升。",
impact:"居民夜歸不再摸黑,社區也少了一分不安。" },
{ status:"協調中", statusKey:"coord", date:"2024/01/20", title:"捷運萬芳站周邊機車停車格增設",
process:"獻瑩團隊接獲通勤族反映後,正協調交通局評估周邊可增設停車格位置。",
result:"評估中,將視場地條件提出方案。",
impact:"未來通勤族停車將更方便,違停情形可望減少。" },
] },
{ key:"zd", name:"政大生活圈", scenario:"學生、居民與通勤族共用的生活路線",
chips:["行人安全","學生通勤動線","河濱步道"],
posDesktop:{top:47,left:45}, posMobile:{top:44,left:50},
cases:[
{ status:"協調中", statusKey:"coord", date:"2024/04/05", title:"指南路人行道拓寬會勘",
process:"獻瑩團隊接獲學生反映後,與里長、工務局現場會勘評估拓寬可行性。",
result:"會勘完成,方案評估中。",
impact:"未來上下課動線將不再需要與車爭道,學生通行更安全。" },
{ status:"持續追蹤", statusKey:"track", date:"2024/02/14", title:"政大周邊機車停車格增設",
process:"獻瑩團隊接獲住戶與學生反映後,協調交通局盤點閒置空間增設停車格。",
result:"部分路段已增設,持續盤點其餘地點。",
impact:"周邊違停情形已略有改善,停車也方便一些。" },
] },
{ key:"gt", name:"公館生活圈", scenario:"商圈、校園與交通節點交會的地方",
chips:["交通改善","商圈環境","公車轉乘"],
posDesktop:{top:27,left:30}, posMobile:{top:15,left:60},
cases:[
{ status:"持續追蹤", statusKey:"track", date:"2024/05/11", title:"公館商圈人行環境改善",
process:"獻瑩團隊接獲居民反映後,協調區公所與警局加強巡查與空間規劃。",
result:"動線已初步改善,持續觀察成效。",
impact:"商圈行走空間變得寬鬆一些,擁擠感稍有緩解。" },
{ status:"已改善", statusKey:"done", date:"2024/03/28", title:"羅斯福路巷弄路平專案",
process:"獻瑩團隊接獲居民反映後,協調道路養護單位排入路平專案施作。",
result:"路面已完成鋪平,通行更順暢。",
impact:"居民騎車、行走不再擔心坑洞,巷弄安全感提升。" },
{ status:"協調中", statusKey:"coord", date:"2024/01/09", title:"公館圓環公車轉乘動線調整",
process:"獻瑩團隊接獲通勤族反映後,協調公運處評估站位調整與指標增設。",
result:"評估中,將提出調整方案。",
impact:"未來轉乘動線有望更直覺,通勤族少走冤枉路。" },
] },
{ key:"da", name:"大安核心", scenario:"巷弄、公園與林蔭生活裡的細節改善",
chips:["巷弄安全","綠美化","公共空間"],
posDesktop:{top:80,left:52}, posMobile:{top:88,left:38},
cases:[
{ status:"協調中", statusKey:"coord", date:"2024/05/18", title:"仁愛里增設UBike站點",
process:"獻瑩團隊接獲里民反映後,協調交通局辦理現場會勘,評估可行位置。",
result:"會勘完成,候選點位評估中。",
impact:"未來最後一哩路的移動將更方便。" },
{ status:"持續追蹤", statusKey:"track", date:"2024/05/16", title:"瑞安街61巷速限與行人安全",
process:"獻瑩團隊接獲居民反映後,協調警局評估標線與速限調整。",
result:"標線調整已提出,持續追蹤執行進度。",
impact:"巷弄車速有望降低,行人跨越風險可望下降。" },
{ status:"已改善", statusKey:"done", date:"2024/04/22", title:"仁愛路林蔭道人行鋪面整平",
process:"獻瑩團隊接獲行人反映後,協調工務局進行鋪面檢修與更換。",
result:"鋪面已完成整平,行走安全提升。",
impact:"居民散步、通勤不再擔心絆倒,林蔭道走起來更安心。" },
{ status:"協調中", statusKey:"coord", date:"2024/03/30", title:"龍陣里社區公園座椅增設",
process:"獻瑩團隊接獲長者反映後,協調公園處評估增設座椅位置與數量。",
result:"評估中,將編列預算逐步增設。",
impact:"未來長者在公園休憩將有更多選擇。" },
{ status:"已改善", statusKey:"done", date:"2024/02/08", title:"龍圖里巷弄招牌安全檢查",
process:"獻瑩團隊接獲居民反映後,協調建管處進行安全檢查並要求改善。",
result:"高風險招牌已完成拆除或補強。",
impact:"巷弄行走不再擔心招牌掉落,居民安心不少。" },
{ status:"持續追蹤", statusKey:"track", date:"2024/01/15", title:"大安森林公園周邊停車動線",
process:"獻瑩團隊接獲居民反映後,協調停管處評估周邊停車格增設可行性。",
result:"部分路段已增設,持續盤點其餘地點。",
impact:"周邊停車一位難求的情況已略有緩解。" },
] },
];
const allHighlights = [
{ title:"安排福興路78巷電線桿地下化", circleTag:"景美", status:"已改善", statusKey:"done",
reflect:"居民反映巷弄電線桿林立,人行動線狹窄、視覺雜亂。", action:"獻瑩協調台電與工務局現勘,要求提出地下化時程。", response:"市府同意安排管線地下化施作。", change:"巷道淨空、行走更安全,街景也更乾淨。" },
{ title:"木柵里國有土地綠美化案", circleTag:"木柵", status:"已改善", statusKey:"done",
reflect:"居民反映閒置國有地雜草叢生,容易成為環境死角。", action:"獻瑩協調財政部國產署與公園處,要求提出活化方案。", response:"市府核定推動綠美化改造。", change:"閒置地變成社區可用的休憩綠地。" },
{ title:"萬芳醫院周邊人行道改善", circleTag:"萬芳", status:"持續追蹤", statusKey:"track",
reflect:"就醫民眾反映人行道狹窄、輪椅通行困難。", action:"獻瑩協調工務局現勘,要求評估拓寬與無障礙改善。", response:"市府提出設計方案,排入施作期程。", change:"等待施作,屆時就醫動線將更順暢安全。" },
{ title:"政大指南路人行道拓寬會勘", circleTag:"政大", status:"協調中", statusKey:"coord",
reflect:"學生反映上下課人潮擁擠、人行道過窄。", action:"獻瑩與里長一同要求工務局現場會勘。", response:"市府完成會勘,正評估拓寬方案。", change:"方案評估中,持續追蹤後續進度。" },
{ title:"羅斯福路巷弄路平專案", circleTag:"公館", status:"已改善", statusKey:"done",
reflect:"居民反映巷弄路面坑洞多,行走與騎車不便。", action:"獻瑩要求道路養護單位排入路平專案施作。", response:"市府完成鋪平作業。", change:"通行更順暢,居民反映安心不少。" },
{ title:"瑞安街61巷速限與行人安全", circleTag:"大安核心", status:"持續追蹤", statusKey:"track",
reflect:"居民反映巷弄車速過快、行人跨越危險。", action:"獻瑩要求警局評估標線與速限調整。", response:"市府提出標線調整方案,持續執行中。", change:"待執行完成後,行人跨越風險可望降低。" },
];
// ---------- STATE ----------
let activeIndex = 0;
let expanded = {};
let hlPage = 0;
const perPage = 3;
const totalPages = Math.ceil(allHighlights.length / perPage);
const mapDesktopEl = document.getElementById("mapDesktop");
const mapMobileTabsEl = document.getElementById("mobileTabs");
const mapMobileImgWrap = document.querySelector(".wsc-mmap-wrap");
const panelEl = document.getElementById("circlePanel");
const hlGridEl = document.getElementById("hlGrid");
const hlDotsEl = document.getElementById("hlDots");
function esc(s){ return s; }
// ---------- RENDER: MAP NODES ----------
function renderMapNodes(){
// clear previous buttons (keep the
![]()
)
mapDesktopEl.querySelectorAll(".wsc-node-btn").forEach(b=>b.remove());
mapMobileImgWrap.querySelectorAll(".wsc-mnode-btn").forEach(b=>b.remove());
circlesData.forEach((c,i)=>{
const active = activeIndex === i;
const short = c.name.replace("生活圈","");
const btn = document.createElement("button");
btn.className = "wsc-node-btn" + (active ? " active":"");
btn.style.top = c.posDesktop.top + "%";
btn.style.left = c.posDesktop.left + "%";
btn.innerHTML = '
'+short+'';
btn.addEventListener("click", ()=>selectCircle(i));
mapDesktopEl.appendChild(btn);
const mbtn = document.createElement("button");
mbtn.className = "wsc-mnode-btn" + (active ? " active":"");
mbtn.style.top = c.posMobile.top + "%";
mbtn.style.left = c.posMobile.left + "%";
mbtn.innerHTML = '
';
mbtn.addEventListener("click", ()=>selectCircle(i));
mapMobileImgWrap.appendChild(mbtn);
});
}
// ---------- RENDER: MOBILE TABS ----------
function renderTabs(){
mapMobileTabsEl.innerHTML = "";
circlesData.forEach((c,i)=>{
const tab = document.createElement("div");
tab.className = "wsc-tab" + (activeIndex===i ? " active":"");
tab.textContent = c.name.replace("生活圈","");
tab.addEventListener("click", ()=>selectCircle(i));
mapMobileTabsEl.appendChild(tab);
});
}
// ---------- RENDER: PANEL ----------
function tagClass(key){ return key==="done" ? "status-done" : key==="track" ? "status-track" : "status-coord"; }
function renderPanel(){
const c = circlesData[activeIndex];
if(!c){ panelEl.style.display="none"; return; }
panelEl.style.display = "block";
const short = c.name.replace("生活圈","");
const previews = allHighlights.filter(h => h.circleTag === short).slice(0,2);
let html = "";
html += '
'+c.name+'
';
html += '
'+c.scenario+'
';
html += '
'+c.chips.map(ch=>'
'+ch+'
').join("")+'
';
html += '
這裡,獻瑩團隊接住的地方問題
';
html += '
';
c.cases.forEach((cs,ci)=>{
const key = c.key+"-"+ci;
const isOpen = !!expanded[key];
html += '
';
html += '
';
html += '
'+cs.date+'
';
html += '
'+cs.status+'
';
html += '
'+cs.title+'
';
html += '
'+(isOpen?"收合":"展開查看")+'
';
html += '
';
html += '
';
html += '
';
html += '
';
html += '
獻瑩怎麼處理:'+cs.process+'
';
html += '
目前結果:'+cs.result+'
';
html += '
對居民的影響:'+cs.impact+'
';
html += '
最近更新:'+cs.date+'
';
html += '
';
html += '
';
html += '
';
});
html += '
';
html += '
代表成果預覽
';
html += '
';
previews.forEach(p=>{
html += '
';
});
html += '
';
html += '
你家附近也有需要被看見的問題嗎?
';
panelEl.innerHTML = html;
panelEl.querySelectorAll(".wsc-case-head").forEach(headEl=>{
headEl.addEventListener("click", ()=>{
const key = headEl.parentElement.getAttribute("data-key");
expanded[key] = !expanded[key];
renderPanel();
});
});
}
function selectCircle(i){
activeIndex = (activeIndex === i) ? activeIndex : i;
activeIndex = i;
expanded = {};
renderMapNodes();
renderTabs();
renderPanel();
}
// ---------- RENDER: HIGHLIGHTS ----------
function renderHighlights(){
hlGridEl.innerHTML = "";
const start = hlPage*perPage;
allHighlights.slice(start, start+perPage).forEach(h=>{
const card = document.createElement("div");
card.className = "wsc-hl-card";
card.innerHTML =
'
'+
'
現場會勘照片佔位
'+
'
'+h.status+'
'+
'
獻瑩追蹤案
'+
'
'+
'
'+
'
'+h.circleTag+'生活圈
'+
'
'+h.title+'
'+
'
'+
'
居民反映:'+h.reflect+'
'+
'
獻瑩出手:'+h.action+'
'+
'
市府回應:'+h.response+'
'+
'
現在改變:'+h.change+'
'+
'
'+
'
';
hlGridEl.appendChild(card);
});
hlDotsEl.innerHTML = "";
for(let i=0;i{ hlPage=i; renderHighlights(); });
hlDotsEl.appendChild(dot);
}
}
document.getElementById("hlPrev").addEventListener("click", ()=>{
hlPage = (hlPage - 1 + totalPages) % totalPages;
renderHighlights();
});
document.getElementById("hlNext").addEventListener("click", ()=>{
hlPage = (hlPage + 1) % totalPages;
renderHighlights();
});
// ---------- MOBILE NAV TOGGLE ----------
document.querySelector(".wsc-nav-toggle").addEventListener("click", function(){
const links = document.querySelector(".wsc-nav-links");
const isShown = links.style.display === "flex";
links.style.display = isShown ? "none" : "flex";
links.style.cssText += "position:absolute;top:76px;left:0;right:0;background:#fff;flex-direction:column;gap:0;padding:8px 20px;border-bottom:1px solid #EDF1F7;z-index:20;";
links.querySelectorAll("div").forEach(d=>{ d.style.padding="12px 0"; });
});
// ---------- INIT ----------
renderMapNodes();
renderTabs();
renderPanel();
renderHighlights();
})();