feat: Dockerize and complete project

This commit is contained in:
mohamad
2026-04-27 17:30:08 +03:30
parent 051148ce78
commit 3c10f5c5ed
62 changed files with 5296 additions and 1 deletions
+28
View File
@@ -0,0 +1,28 @@
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="{% block meta_description %}Tecvico Corp — Advanced Medical Imaging & Radiomics Solutions{% endblock %}" />
<title>{% block title %}Tecvico Corp{% endblock %} | Tecvico</title>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap" rel="stylesheet" />
<link rel="stylesheet" href="{% static 'css/main.css' %}" />
{% block extra_css %}{% endblock %}
</head>
<body>
{% include "partials/_navbar.html" %}
<main id="main-content">
{% block content %}{% endblock %}
</main>
{% include "partials/_footer.html" %}
<script src="{% static 'js/main.js' %}"></script>
{% block extra_js %}{% endblock %}
</body>
</html>
+117
View File
@@ -0,0 +1,117 @@
{% extends "base.html" %}
{% load static %}
{% block title %}What is Tecvico{% endblock %}
{% block meta_description %}Learn about Tecvico Corp and ViSERA — Visualized & Standardized Environment for Radiomics Analysis, developed at UBC and BC Cancer Research Institute.{% endblock %}
{% block content %}
<section class="page-hero" aria-labelledby="page-hero-heading">
<div class="page-hero-blobs" aria-hidden="true">
<div class="blob blob--1"></div>
<div class="blob blob--2"></div>
</div>
<div class="container">
<div class="page-hero-content">
<div class="section-badge">About</div>
<h1 class="page-hero-title" id="page-hero-heading">What is Tecvico?</h1>
<p class="page-hero-subtitle">
Visualized &amp; Standardized Environment for Radiomics Analysis
</p>
</div>
</div>
</section>
<section class="section" aria-labelledby="about-intro-heading">
<div class="container">
<div class="about-intro glass-card fade-in">
<div class="about-intro-text">
<h2 id="about-intro-heading">Desktop Software for Medical Imaging Research</h2>
<ul class="about-list">
<li>Desktop software to improve usability, reusability, and reproducibility in medical imaging &amp; healthcare research.</li>
<li>Development platform to create reproducible research workflows by connecting different tools.</li>
<li>Useful for collaborative research projects and for ensuring consistency across different studies.</li>
<li>User-friendly for different expertise levels, including radiation oncologists, radiologists, physicists &amp; data scientists.</li>
</ul>
</div>
</div>
</div>
</section>
<section class="section" aria-labelledby="standardization-heading">
<div class="container">
<div class="section-header">
<div class="section-badge">Standards</div>
<h2 class="section-title" id="standardization-heading">Standardization</h2>
</div>
<div class="standards-grid">
<div class="standard-card glass-card fade-in">
<div class="standard-badge">IBSI 1.0</div>
<h3 class="standard-title">Radiomic Feature Extraction</h3>
<p class="standard-desc">
ViSERA is a python-based open-source package that enables standardized and
reproducible radiomic feature extraction in compliance with the Image Biomarker
Standardization Initiative (IBSI 1.0).
</p>
</div>
<div class="standard-card glass-card fade-in">
<div class="standard-badge">IBSI 2.0</div>
<h3 class="standard-title">Image Filtering</h3>
<p class="standard-desc">
Image filters have been standardized against IBSI 2.0 by implementing and
validating several filter options, ensuring reproducibility across research
institutions worldwide.
</p>
</div>
<div class="standard-card glass-card fade-in">
<div class="standard-badge">Python</div>
<h3 class="standard-title">Open Source</h3>
<p class="standard-desc">
ViSERA is a major, entirely-revamped upgrade to the original SERA (Matlab-based),
now built on Python for broader accessibility and community contribution.
</p>
</div>
<div class="standard-card glass-card fade-in">
<div class="standard-badge">End-to-End</div>
<h3 class="standard-title">Standardized Workflows</h3>
<p class="standard-desc">
ViSERA employs a number of popular image processing algorithms to create
end-to-end standardized workflows for consistent, reproducible research results.
</p>
</div>
</div>
</div>
</section>
<section class="section" aria-labelledby="history-heading">
<div class="container">
<div class="history-block glass-card fade-in">
<div class="history-content">
<div class="section-badge">History</div>
<h2 id="history-heading">Our Origins</h2>
<p>
Tecvico (formerly known as Visera) has been developing since 2021 by the
Quantitative Radiomolecular Imaging and Therapy (Qurit) lab &amp; program at the
University of British Columbia &amp; BC Cancer Research Institute, Vancouver, BC, Canada.
</p>
<p>
Our mission is to bridge the gap between cutting-edge radiomics research and
practical clinical application by providing standardized, reproducible, and
user-friendly software tools.
</p>
<div class="history-links">
<a href="https://www.qurit.ca" class="btn-ghost" target="_blank" rel="noopener noreferrer">Qurit Lab</a>
<a href="https://www.ubc.ca" class="btn-ghost" target="_blank" rel="noopener noreferrer">UBC</a>
<a href="https://www.bccrc.ca" class="btn-ghost" target="_blank" rel="noopener noreferrer">BC Cancer</a>
</div>
</div>
<div class="history-visual" aria-hidden="true">
<div class="history-blob history-blob--1"></div>
<div class="history-blob history-blob--2"></div>
<div class="history-year">2021</div>
</div>
</div>
</div>
</section>
{% endblock %}
+80
View File
@@ -0,0 +1,80 @@
{% extends "base.html" %}
{% load static %}
{% block title %}Contact{% endblock %}
{% block meta_description %}Contact Tecvico Corp — support for ViSERA software and general inquiries.{% endblock %}
{% block content %}
<section class="page-hero" aria-labelledby="contact-heading">
<div class="page-hero-blobs" aria-hidden="true">
<div class="blob blob--1"></div>
<div class="blob blob--2"></div>
</div>
<div class="container">
<div class="page-hero-content">
<div class="section-badge">Get in Touch</div>
<h1 class="page-hero-title" id="contact-heading">Contact Us</h1>
<p class="page-hero-subtitle">Support for ViSERA software is available via email and Discord.</p>
</div>
</div>
</section>
<section class="section" aria-labelledby="contact-details-heading">
<div class="container">
<h2 class="sr-only" id="contact-details-heading">Contact Details</h2>
<div class="contact-grid">
<div class="contact-card glass-card fade-in">
<div class="contact-icon" aria-hidden="true">
<svg width="32" height="32" viewBox="0 0 32 32" fill="none">
<path d="M5 8C5 6.895 5.895 6 7 6H25C26.105 6 27 6.895 27 8V22C27 23.105 26.105 24 25 24H7C5.895 24 5 23.105 5 22V8Z" stroke="currentColor" stroke-width="1.5"/>
<path d="M5 9L16 16L27 9" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>
</svg>
</div>
<h3 class="contact-card-title">Email Support</h3>
<p class="contact-card-desc">
For software support and general inquiries, reach us at:
</p>
<a href="mailto:support@tecvico.com" class="contact-email-link">
support@tecvico.com
</a>
</div>
<div class="contact-card glass-card fade-in">
<div class="contact-icon" aria-hidden="true">
<svg width="32" height="32" viewBox="0 0 24 24" fill="currentColor">
<path d="M20.317 4.37a19.791 19.791 0 0 0-4.885-1.515.074.074 0 0 0-.079.037c-.21.375-.444.864-.608 1.25a18.27 18.27 0 0 0-5.487 0 12.64 12.64 0 0 0-.617-1.25.077.077 0 0 0-.079-.037A19.736 19.736 0 0 0 3.677 4.37a.07.07 0 0 0-.032.027C.533 9.046-.32 13.58.099 18.057.1 18.08.114 18.1.133 18.11a19.9 19.9 0 0 0 5.993 3.03.078.078 0 0 0 .084-.028c.462-.63.874-1.295 1.226-1.994a.076.076 0 0 0-.041-.106 13.107 13.107 0 0 1-1.872-.892.077.077 0 0 1-.008-.128 10.2 10.2 0 0 0 .372-.292.074.074 0 0 1 .077-.01c3.928 1.793 8.18 1.793 12.062 0a.074.074 0 0 1 .078.01c.12.098.246.198.373.292a.077.077 0 0 1-.006.127 12.299 12.299 0 0 1-1.873.892.077.077 0 0 0-.041.107c.36.698.772 1.362 1.225 1.993a.076.076 0 0 0 .084.028 19.839 19.839 0 0 0 6.002-3.03.077.077 0 0 0 .032-.054c.5-5.177-.838-9.674-3.549-13.66a.061.061 0 0 0-.031-.03z"/>
</svg>
</div>
<h3 class="contact-card-title">Discord Community</h3>
<p class="contact-card-desc">
Join our Discord server for community support, feature discussions, and announcements.
</p>
<a href="https://discord.gg/9XxA6pV9hb" class="btn-primary" target="_blank" rel="noopener noreferrer">
Join Discord Forum
</a>
</div>
<div class="contact-card glass-card fade-in">
<div class="contact-icon" aria-hidden="true">
<svg width="32" height="32" viewBox="0 0 32 32" fill="none">
<path d="M16 3C11.029 3 7 7.029 7 12C7 19 16 29 16 29C16 29 25 19 25 12C25 7.029 20.971 3 16 3Z" stroke="currentColor" stroke-width="1.5"/>
<circle cx="16" cy="12" r="3" stroke="currentColor" stroke-width="1.5"/>
</svg>
</div>
<h3 class="contact-card-title">Office Address</h3>
<address class="contact-address">
<p>BC Cancer Research Center</p>
<p>675 West 10th Ave</p>
<p>Office 6-112</p>
<p>Vancouver, BC, V5Z 1L3</p>
<p>Canada</p>
</address>
</div>
</div>
</div>
</section>
{% endblock %}
+130
View File
@@ -0,0 +1,130 @@
{% extends "base.html" %}
{% load static %}
{% block title %}Downloads{% endblock %}
{% block meta_description %}Download ViSERA by Tecvico — available for Windows, macOS, and Linux.{% endblock %}
{% block content %}
<section class="page-hero" aria-labelledby="downloads-heading">
<div class="page-hero-blobs" aria-hidden="true">
<div class="blob blob--1"></div>
<div class="blob blob--2"></div>
</div>
<div class="container">
<div class="page-hero-content">
<div class="section-badge">Software</div>
<h1 class="page-hero-title" id="downloads-heading">Downloads</h1>
<p class="page-hero-subtitle">Download the latest version of ViSERA for your platform.</p>
</div>
</div>
</section>
<section class="section" aria-labelledby="download-platforms-heading">
<div class="container">
<h2 class="sr-only" id="download-platforms-heading">Available Platforms</h2>
<div class="downloads-grid">
<div class="download-card glass-card fade-in {% if not windows_items %}download-card--unavailable{% endif %}">
<div class="download-platform-icon" aria-hidden="true">
<svg width="48" height="48" viewBox="0 0 24 24" fill="currentColor">
<path d="M0 3.449L9.75 2.1v9.451H0m10.949-9.602L24 0v11.4H10.949M0 12.6h9.75v9.451L0 20.699M10.949 12.6H24V24l-12.9-1.801"/>
</svg>
</div>
<h3 class="download-platform-name">Windows</h3>
<p class="download-platform-desc">Windows 10 and up (64-bit)</p>
{% if windows_items %}
{% for item in windows_items %}
<div class="download-item">
<span class="download-version">v{{ item.version }}</span>
{% if item.description %}<p class="download-item-desc">{{ item.description }}</p>{% endif %}
{% if item.download_url and item.download_url != '#' %}
<a href="{{ item.download_url }}" class="btn-primary download-btn" download>
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" aria-hidden="true">
<path d="M9 2V12M9 12L5 8M9 12L13 8M3 15H15" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
Download
</a>
{% endif %}
</div>
{% endfor %}
{% else %}
<span class="coming-soon-badge">Coming Soon</span>
{% endif %}
</div>
<div class="download-card glass-card fade-in {% if not macos_items %}download-card--unavailable{% endif %}">
<div class="download-platform-icon" aria-hidden="true">
<svg width="48" height="48" viewBox="0 0 24 24" fill="currentColor">
<path d="M18.71 19.5c-.83 1.24-1.71 2.45-3.05 2.47-1.34.03-1.77-.79-3.29-.79-1.53 0-2 .77-3.27.82-1.31.05-2.3-1.32-3.14-2.53C4.25 17 2.94 12.45 4.7 9.39c.87-1.52 2.43-2.48 4.12-2.51 1.28-.02 2.5.87 3.29.87.78 0 2.26-1.07 3.8-.91.65.03 2.47.26 3.64 1.98-.09.06-2.17 1.28-2.15 3.81.03 3.02 2.65 4.03 2.68 4.04-.03.07-.42 1.44-1.38 2.83M13 3.5c.73-.83 1.94-1.46 2.94-1.5.13 1.17-.34 2.35-1.04 3.19-.69.85-1.83 1.51-2.95 1.42-.15-1.15.41-2.35 1.05-3.11z"/>
</svg>
</div>
<h3 class="download-platform-name">macOS</h3>
<p class="download-platform-desc">macOS 11 Big Sur and up</p>
{% if macos_items %}
{% for item in macos_items %}
<div class="download-item">
<span class="download-version">v{{ item.version }}</span>
{% if item.description %}<p class="download-item-desc">{{ item.description }}</p>{% endif %}
{% if item.download_url and item.download_url != '#' %}
<a href="{{ item.download_url }}" class="btn-primary download-btn" download>
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" aria-hidden="true">
<path d="M9 2V12M9 12L5 8M9 12L13 8M3 15H15" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
Download
</a>
{% endif %}
</div>
{% endfor %}
{% else %}
<span class="coming-soon-badge">Coming Soon</span>
{% endif %}
</div>
<div class="download-card glass-card fade-in {% if not linux_items %}download-card--unavailable{% endif %}">
<div class="download-platform-icon" aria-hidden="true">
<svg width="48" height="48" viewBox="0 0 24 24" fill="currentColor">
<path d="M12.504 0c-.155 0-.315.008-.48.021-4.226.333-3.105 4.807-3.17 6.298-.076 1.092-.3 1.953-1.05 3.02-.885 1.051-2.127 2.75-2.716 4.521-.278.832-.41 1.684-.287 2.489a.424.424 0 00-.11.135c-.26.268-.45.6-.663.839-.199.199-.485.267-.797.4-.313.136-.658.269-.864.68-.09.189-.136.394-.132.602 0 .199.027.4.055.536.058.399.116.728.04.97-.249.68-.28 1.145-.106 1.484.174.334.535.47.94.601.81.2 1.91.135 2.774.6.926.466 1.866.67 2.616.47.526-.116.97-.464 1.208-.946.587-.003 1.23-.EraseINIT.3.337.572.95.23 1.681-.078.277-.21.557-.303.815-.125.35-.169.63-.046.875.315.648 1.086.698 1.728.hyperparameter698.256 0 .504-.034.72-.046.372-.022.626.026.783.17.428.39.405 1.353.504 2.408.096.99.184 2.023.618 2.813.22.391.528.717.938.939.41.22.915.316 1.44.282.52-.033 1.092-.218 1.544-.668.296-.296.522-.723.58-1.226.029-.248.017-.51-.02-.77-.15-1.168.056-2.22.617-2.82.274-.294.548-.452.748-.606.238-.186.427-.41.554-.676.247-.517.194-1.107-.026-1.633-.11-.271-.238-.517-.324-.773-.148-.448-.172-.913.053-1.377.226-.467.67-.876 1.02-1.428a.424.424 0 00.11-.134c.25-.43.31-.915.245-1.395-.065-.476-.245-.937-.49-1.37-.245-.436-.54-.838-.807-1.278-.254-.428-.47-.903-.522-1.445-.1-.994.268-2.1.368-3.158.05-.53.04-1.046-.059-1.518-.097-.47-.3-.9-.616-1.24-.636-.68-1.608-.904-2.527-.974-.45-.035-.899-.026-1.334.026zm.042 1.174c.42-.047.852-.056 1.277-.022.812.062 1.59.262 2.047.758.228.245.37.554.44.918.073.366.08.78.03 1.233-.103 1.055-.486 2.198-.36 3.34.061.567.302 1.09.575 1.56.27.46.572.876.822 1.319.25.443.43.904.483 1.362.053.45.003.895-.2 1.269a.37.37 0 00-.099.11c-.35.56-.83.993-1.1 1.57-.28.587-.295 1.218-.12 1.822.088.3.215.585.33.869.217.526.253 1.015.066 1.4a1.088 1.088 0 01-.354.43c-.22.162-.502.322-.806.638-.7.742-.924 1.963-.756 3.254.028.207.038.414.013.605-.045.38-.19.688-.41.908-.33.335-.765.497-1.178.524-.414.027-.83-.054-1.14-.22-.315-.169-.54-.43-.691-.714-.358-.647-.445-1.572-.54-2.553-.1-1.012-.118-2.066-.67-2.593-.269-.247-.645-.345-1.117-.32-.232.014-.455.047-.677.047-.44 0-.836-.054-.97-.33-.065-.133-.073-.36.043-.688.1-.29.238-.586.292-.866.133-.676.05-1.313-.313-1.75-.364-.44-1.027-.604-1.718-.777-.69-.176-1.44-.396-1.582-.862-.092-.302-.06-.666.11-1.127.087-.23.097-.482.054-.727-.083-.499.053-.986.22-1.427.246-.66 1.463-2.382 2.39-3.479.87-1.044 1.15-2.02 1.22-3.167.063-1.26-.744-5.02 2.57-5.27z"/>
</svg>
</div>
<h3 class="download-platform-name">Linux</h3>
<p class="download-platform-desc">Ubuntu 20.04+ and compatible distributions</p>
{% if linux_items %}
{% for item in linux_items %}
<div class="download-item">
<span class="download-version">v{{ item.version }}</span>
{% if item.description %}<p class="download-item-desc">{{ item.description }}</p>{% endif %}
{% if item.download_url and item.download_url != '#' %}
<a href="{{ item.download_url }}" class="btn-primary download-btn" download>
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" aria-hidden="true">
<path d="M9 2V12M9 12L5 8M9 12L13 8M3 15H15" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
Download
</a>
{% endif %}
</div>
{% endfor %}
{% else %}
<span class="coming-soon-badge">Coming Soon</span>
{% endif %}
</div>
</div>
</div>
</section>
<section class="section" aria-labelledby="reinstall-heading">
<div class="container">
<div class="info-block glass-card fade-in">
<h2 id="reinstall-heading">Installation Notes</h2>
<p>
If you have installed an older version of ViSERA, you can install the new version
over it without removing the previous installation. However, if you encounter any
problems, please remove the old version first before reinstalling.
</p>
<a href="{% url 'pages:faq' %}" class="btn-ghost">View Full FAQ</a>
</div>
</div>
</section>
{% endblock %}
+65
View File
@@ -0,0 +1,65 @@
{% extends "base.html" %}
{% load static %}
{% block title %}FAQ{% endblock %}
{% block meta_description %}Frequently asked questions about ViSERA by Tecvico — licensing, citation, system requirements, and more.{% endblock %}
{% block content %}
<section class="page-hero" aria-labelledby="faq-heading">
<div class="page-hero-blobs" aria-hidden="true">
<div class="blob blob--1"></div>
<div class="blob blob--2"></div>
</div>
<div class="container">
<div class="page-hero-content">
<div class="section-badge">Help</div>
<h1 class="page-hero-title" id="faq-heading">FAQ</h1>
<p class="page-hero-subtitle">Frequently Asked Questions</p>
</div>
</div>
</section>
<section class="section" aria-labelledby="faq-list-heading">
<div class="container">
<h2 class="sr-only" id="faq-list-heading">FAQ List</h2>
{% if faq_entries %}
<div class="faq-list">
{% for entry in faq_entries %}
<div class="faq-item glass-card fade-in">
<button
class="faq-question"
aria-expanded="false"
aria-controls="faq-answer-{{ entry.pk }}"
id="faq-question-{{ entry.pk }}"
>
{{ entry.question }}
<svg class="faq-icon" width="20" height="20" viewBox="0 0 20 20" fill="none" aria-hidden="true">
<path d="M5 8L10 13L15 8" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
</button>
<div
class="faq-answer"
id="faq-answer-{{ entry.pk }}"
role="region"
aria-labelledby="faq-question-{{ entry.pk }}"
hidden
>
<p>{{ entry.answer }}</p>
</div>
</div>
{% endfor %}
</div>
{% else %}
<p class="empty-state">No FAQ entries available yet.</p>
{% endif %}
<div class="faq-contact glass-card fade-in">
<h2>Still Have Questions?</h2>
<p>Can't find the answer you're looking for? Get in touch with our support team.</p>
<a href="{% url 'pages:contact' %}" class="btn-primary">Contact Support</a>
</div>
</div>
</section>
{% endblock %}
+188
View File
@@ -0,0 +1,188 @@
{% extends "base.html" %}
{% load static %}
{% block title %}Home{% endblock %}
{% block meta_description %}Tecvico Corp — A Powerful Workflow Generator for Standardized Radiomics Analysis and Medical Image Visualization.{% endblock %}
{% block content %}
<section class="hero" aria-labelledby="hero-heading">
<div class="hero-blobs" aria-hidden="true">
<div class="blob blob--1"></div>
<div class="blob blob--2"></div>
<div class="blob blob--3"></div>
</div>
<div class="container hero-content">
<div class="hero-badge">Developing since 2021</div>
<h1 class="hero-title" id="hero-heading">
Tecvico,
<br />
<span class="gradient-text">A Powerful Workflow Generator</span>
</h1>
<p class="hero-subtitle">
for Standardized Radiomics Analysis and Medical Image Visualization
</p>
<p class="hero-description">
ViSERA is a free, open-source software specialized for visualization, processing,
segmentation, registration, fusion and analysis of medical and biomedical images,
including radiomics and machine learning analysis.
</p>
<div class="hero-actions">
<a href="{% url 'pages:downloads' %}" class="btn-primary">Download Now</a>
<a href="{% url 'pages:about' %}" class="btn-ghost">About Tecvico</a>
</div>
</div>
</section>
<section class="section features-section" aria-labelledby="features-heading">
<div class="container">
<div class="section-header">
<div class="section-badge">Capabilities</div>
<h2 class="section-title" id="features-heading">Important Features</h2>
<p class="section-desc">
Comprehensive tools for medical imaging research, standardized and reproducible.
</p>
</div>
<div class="features-grid">
{% for feature in features %}
<div class="feature-card glass-card fade-in">
<div class="feature-icon" aria-hidden="true">{{ feature.icon }}</div>
<h3 class="feature-title">{{ feature.title }}</h3>
<p class="feature-desc">{{ feature.desc }}</p>
</div>
{% empty %}
<div class="feature-card glass-card fade-in">
<div class="feature-icon" aria-hidden="true">⚗️</div>
<h3 class="feature-title">Image Filtering</h3>
<p class="feature-desc">Standardized image filtering techniques compliant with IBSI 2.0 guidelines.</p>
</div>
<div class="feature-card glass-card fade-in">
<div class="feature-icon" aria-hidden="true">🖥️</div>
<h3 class="feature-title">Professional Viewer</h3>
<p class="feature-desc">Comfortable, professional medical image viewer with multi-modality support.</p>
</div>
<div class="feature-card glass-card fade-in">
<div class="feature-icon" aria-hidden="true">📊</div>
<h3 class="feature-title">Radiomics Features</h3>
<p class="feature-desc">Handcrafted radiomics feature generation standardized by IBSI 1.0.</p>
</div>
<div class="feature-card glass-card fade-in">
<div class="feature-icon" aria-hidden="true">🔄</div>
<h3 class="feature-title">Format Support</h3>
<p class="feature-desc">NIFTI, DICOM, NRRD, and more — comprehensive multi-format support.</p>
</div>
<div class="feature-card glass-card fade-in">
<div class="feature-icon" aria-hidden="true">🗂️</div>
<h3 class="feature-title">Image Registration</h3>
<p class="feature-desc">Advanced image registration, fusion, and standardized SUV conversion.</p>
</div>
<div class="feature-card glass-card fade-in">
<div class="feature-icon" aria-hidden="true">🔬</div>
<h3 class="feature-title">RT Struct Support</h3>
<p class="feature-desc">Full RT struct support for radiation oncology workflows and research.</p>
</div>
{% endfor %}
</div>
</div>
</section>
{% if nav_main_products %}
<section class="section products-section" aria-labelledby="products-heading">
<div class="container">
<div class="section-header">
<div class="section-badge">Our Software</div>
<h2 class="section-title" id="products-heading">Products</h2>
<p class="section-desc">Explore our suite of medical imaging and radiomics tools.</p>
</div>
<div class="products-grid">
{% for product in nav_main_products %}
<a href="{{ product.get_absolute_url }}" class="product-card glass-card fade-in">
{% if product.image %}
<div class="product-card-image">
<img src="{{ product.image.url }}" alt="{{ product.name }}" loading="lazy" />
</div>
{% endif %}
<div class="product-card-body">
<h3 class="product-card-title">{{ product.name }}</h3>
<p class="product-card-desc">{{ product.short_description }}</p>
<span class="product-card-link">
Explore
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true">
<path d="M3 8H13M13 8L9 4M13 8L9 12" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
</span>
</div>
</a>
{% endfor %}
</div>
</div>
</section>
{% endif %}
<section class="section problems-section" aria-labelledby="problems-heading">
<div class="container">
<div class="section-header">
<div class="section-badge">Value Proposition</div>
<h2 class="section-title" id="problems-heading">What Problems Does Tecvico Solve?</h2>
</div>
<div class="problems-grid">
<div class="problem-item glass-card fade-in">
<div class="problem-number" aria-hidden="true">01</div>
<h3 class="problem-title">Accessibility</h3>
<p class="problem-desc">
Tecvico provides a user-friendly interface and a wide range of tools, allowing
researchers to perform complex data analysis without extensive technical knowledge
or programming expertise.
</p>
</div>
<div class="problem-item glass-card fade-in">
<div class="problem-number" aria-hidden="true">02</div>
<h3 class="problem-title">Integrated Tools</h3>
<p class="problem-desc">
Tecvico integrates a vast collection of tools and resources from various domains
of healthcare and medical imaging research in a common, unified environment.
</p>
</div>
<div class="problem-item glass-card fade-in">
<div class="problem-number" aria-hidden="true">03</div>
<h3 class="problem-title">Flexibility</h3>
<p class="problem-desc">
Tecvico offers flexibility in terms of tool optimization and workflow customization
to match your specific research requirements.
</p>
</div>
<div class="problem-item glass-card fade-in">
<div class="problem-number" aria-hidden="true">04</div>
<h3 class="problem-title">Reproducibility</h3>
<p class="problem-desc">
Improve usability, reusability, and reproducibility (URR) through a workflow
management system that allows researchers to easily create, share, and reuse
analysis pipelines.
</p>
</div>
</div>
</div>
</section>
<section class="section about-strip" aria-labelledby="about-strip-heading">
<div class="container">
<div class="about-strip-inner glass-card">
<div class="about-strip-content">
<div class="section-badge">Our Story</div>
<h2 class="section-title" id="about-strip-heading">More to Know</h2>
<p class="about-strip-text">
Tecvico has been developing since 2021 by the Quantitative Radiomolecular Imaging
and Therapy (Qurit) lab &amp; program at the University of British Columbia &amp;
BC Cancer Research Institute, Vancouver, BC, Canada.
</p>
<a href="{% url 'pages:about' %}" class="btn-primary">Learn More</a>
</div>
<div class="about-strip-blobs" aria-hidden="true">
<div class="strip-blob strip-blob--1"></div>
<div class="strip-blob strip-blob--2"></div>
</div>
</div>
</div>
</section>
{% endblock %}
+73
View File
@@ -0,0 +1,73 @@
{% load static %}
<footer class="footer" role="contentinfo">
<div class="footer-blobs" aria-hidden="true">
<div class="footer-blob footer-blob--1"></div>
<div class="footer-blob footer-blob--2"></div>
</div>
<div class="container">
<div class="footer-grid">
<div class="footer-brand-col">
<a href="{% url 'pages:home' %}" class="footer-logo" aria-label="Tecvico home">
<span class="brand-icon">T</span>
<span class="brand-name">Tecvico</span>
</a>
<p class="footer-tagline">
Advancing medical imaging and radiomics research through innovative, standardized software solutions.
</p>
<a href="https://discord.gg/9XxA6pV9hb" class="btn-ghost btn-sm" target="_blank" rel="noopener noreferrer">
<svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
<path d="M20.317 4.37a19.791 19.791 0 0 0-4.885-1.515.074.074 0 0 0-.079.037c-.21.375-.444.864-.608 1.25a18.27 18.27 0 0 0-5.487 0 12.64 12.64 0 0 0-.617-1.25.077.077 0 0 0-.079-.037A19.736 19.736 0 0 0 3.677 4.37a.07.07 0 0 0-.032.027C.533 9.046-.32 13.58.099 18.057.1 18.08.114 18.1.133 18.11a19.9 19.9 0 0 0 5.993 3.03.078.078 0 0 0 .084-.028c.462-.63.874-1.295 1.226-1.994a.076.076 0 0 0-.041-.106 13.107 13.107 0 0 1-1.872-.892.077.077 0 0 1-.008-.128 10.2 10.2 0 0 0 .372-.292.074.074 0 0 1 .077-.01c3.928 1.793 8.18 1.793 12.062 0a.074.074 0 0 1 .078.01c.12.098.246.198.373.292a.077.077 0 0 1-.006.127 12.299 12.299 0 0 1-1.873.892.077.077 0 0 0-.041.107c.36.698.772 1.362 1.225 1.993a.076.076 0 0 0 .084.028 19.839 19.839 0 0 0 6.002-3.03.077.077 0 0 0 .032-.054c.5-5.177-.838-9.674-3.549-13.66a.061.061 0 0 0-.031-.03z"/>
</svg>
Join Discord
</a>
</div>
<div class="footer-links-col">
<h3 class="footer-heading">Navigation</h3>
<ul class="footer-links" role="list">
<li><a href="{% url 'pages:home' %}">Home</a></li>
<li><a href="{% url 'pages:about' %}">What is Tecvico</a></li>
<li><a href="{% url 'products:overview' %}">Products</a></li>
<li><a href="{% url 'pages:downloads' %}">Downloads</a></li>
<li><a href="{% url 'pages:faq' %}">FAQ</a></li>
<li><a href="{% url 'pages:contact' %}">Contact</a></li>
</ul>
</div>
{% if nav_main_products %}
<div class="footer-links-col">
<h3 class="footer-heading">Products</h3>
<ul class="footer-links" role="list">
{% for product in nav_main_products %}
<li><a href="{{ product.get_absolute_url }}">{{ product.name }}</a></li>
{% endfor %}
</ul>
</div>
{% endif %}
<div class="footer-contact-col">
<h3 class="footer-heading">Contact</h3>
<address class="footer-address">
<p>BC Cancer Research Center</p>
<p>675 West 10th Ave, Office 6-112</p>
<p>Vancouver, BC, V5Z 1L3</p>
</address>
<a href="mailto:support@tecvico.com" class="footer-email">support@tecvico.com</a>
</div>
</div>
<div class="footer-bottom">
<p class="footer-copy">
&copy; {% now "Y" %} Tecvico Corp. All rights reserved. Formerly known as Visera.
</p>
<p class="footer-credit">
Developed at <a href="https://www.qurit.ca" target="_blank" rel="noopener noreferrer">Qurit Lab</a>,
<a href="https://www.ubc.ca" target="_blank" rel="noopener noreferrer">University of British Columbia</a>
&amp; <a href="https://www.bccrc.ca" target="_blank" rel="noopener noreferrer">BC Cancer Research Institute</a>
</p>
</div>
</div>
</footer>
+97
View File
@@ -0,0 +1,97 @@
{% load static %}
<nav class="navbar" id="navbar" role="navigation" aria-label="Main navigation">
<div class="navbar-container">
<a href="{% url 'pages:home' %}" class="navbar-brand" aria-label="Tecvico home">
<span class="brand-icon">T</span>
<span class="brand-name">Tecvico</span>
</a>
<button class="navbar-toggle" id="navbarToggle" aria-expanded="false" aria-controls="navbarMenu" aria-label="Toggle navigation">
<span class="toggle-bar"></span>
<span class="toggle-bar"></span>
<span class="toggle-bar"></span>
</button>
<div class="navbar-menu" id="navbarMenu">
<ul class="nav-list" role="list">
<li class="nav-item">
<a href="{% url 'pages:home' %}" class="nav-link {% if request.resolver_match.url_name == 'home' %}active{% endif %}">
Home
</a>
</li>
{% if nav_main_products %}
<li class="nav-item has-megamenu" id="productsNavItem">
<a href="{% url 'products:overview' %}" class="nav-link {% if 'products' in request.resolver_match.namespace %}active{% endif %}" aria-haspopup="true" aria-expanded="false" id="productsTrigger">
Products
<svg class="nav-arrow" width="12" height="12" viewBox="0 0 12 12" fill="none" aria-hidden="true">
<path d="M2 4L6 8L10 4" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
</a>
<div class="megamenu" role="menu" aria-labelledby="productsTrigger">
<div class="megamenu-inner">
<div class="megamenu-grid">
{% for product in nav_main_products %}
<div class="megamenu-column">
<a href="{{ product.get_absolute_url }}" class="megamenu-product-title" role="menuitem">
{{ product.name }}
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" aria-hidden="true">
<path d="M3 7H11M11 7L8 4M11 7L8 10" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
</a>
<p class="megamenu-product-desc">{{ product.short_description }}</p>
{% with subs=product.sub_products.all %}
{% if subs %}
<ul class="megamenu-sublist" role="list">
{% for sub in subs %}
{% if sub.is_active %}
<li>
<a href="{{ sub.get_absolute_url }}" class="megamenu-sublink" role="menuitem">
<span class="sublink-dot"></span>
{{ sub.name }}
</a>
</li>
{% endif %}
{% endfor %}
</ul>
{% endif %}
{% endwith %}
</div>
{% endfor %}
</div>
</div>
</div>
</li>
{% endif %}
<li class="nav-item">
<a href="{% url 'pages:about' %}" class="nav-link {% if request.resolver_match.url_name == 'about' %}active{% endif %}">
What is Tecvico
</a>
</li>
<li class="nav-item">
<a href="{% url 'pages:downloads' %}" class="nav-link {% if request.resolver_match.url_name == 'downloads' %}active{% endif %}">
Downloads
</a>
</li>
<li class="nav-item">
<a href="{% url 'pages:faq' %}" class="nav-link {% if request.resolver_match.url_name == 'faq' %}active{% endif %}">
FAQ
</a>
</li>
<li class="nav-item">
<a href="{% url 'pages:contact' %}" class="nav-link nav-link--cta {% if request.resolver_match.url_name == 'contact' %}active{% endif %}">
Contact
</a>
</li>
</ul>
</div>
</div>
</nav>
+88
View File
@@ -0,0 +1,88 @@
{% extends "base.html" %}
{% load static %}
{% block title %}{{ main_product.name }}{% endblock %}
{% block meta_description %}{{ main_product.short_description }}{% endblock %}
{% block content %}
<section class="page-hero" aria-labelledby="main-product-heading">
<div class="page-hero-blobs" aria-hidden="true">
<div class="blob blob--1"></div>
<div class="blob blob--2"></div>
<div class="blob blob--3"></div>
</div>
<div class="container">
<nav class="breadcrumb" aria-label="Breadcrumb">
<ol class="breadcrumb-list" role="list">
<li><a href="{% url 'pages:home' %}">Home</a></li>
<li aria-hidden="true" class="breadcrumb-sep"></li>
<li><a href="{% url 'products:overview' %}">Products</a></li>
<li aria-hidden="true" class="breadcrumb-sep"></li>
<li aria-current="page">{{ main_product.name }}</li>
</ol>
</nav>
<div class="page-hero-content">
<div class="section-badge">Product</div>
<h1 class="page-hero-title" id="main-product-heading">{{ main_product.name }}</h1>
<p class="page-hero-subtitle">{{ main_product.short_description }}</p>
</div>
</div>
</section>
<section class="section" aria-labelledby="product-desc-heading">
<div class="container">
<div class="product-detail-intro glass-card fade-in">
<h2 class="sr-only" id="product-desc-heading">About {{ main_product.name }}</h2>
{% if main_product.image %}
<div class="product-detail-image">
<img src="{{ main_product.image.url }}" alt="{{ main_product.name }}" loading="lazy" />
</div>
{% endif %}
<div class="product-detail-text">
<p class="product-detail-desc">{{ main_product.description }}</p>
</div>
</div>
</div>
</section>
{% with subs=main_product.sub_products.all %}
{% if subs %}
<section class="section" aria-labelledby="subproducts-heading">
<div class="container">
<div class="section-header">
<div class="section-badge">Modules</div>
<h2 class="section-title" id="subproducts-heading">{{ main_product.name }} Modules</h2>
<p class="section-desc">
Explore the different modules and capabilities within {{ main_product.name }}.
</p>
</div>
<div class="subproducts-grid">
{% for sub in subs %}
{% if sub.is_active %}
<a href="{{ sub.get_absolute_url }}" class="subproduct-card glass-card fade-in">
{% if sub.image %}
<div class="subproduct-card-image">
<img src="{{ sub.image.url }}" alt="{{ sub.name }}" loading="lazy" />
</div>
{% endif %}
<div class="subproduct-card-body">
<h3 class="subproduct-card-title">{{ sub.name }}</h3>
<p class="subproduct-card-desc">{{ sub.short_description }}</p>
<span class="subproduct-card-link">
Learn More
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" aria-hidden="true">
<path d="M3 7H11M11 7L8 4M11 7L8 10" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
</span>
</div>
</a>
{% endif %}
{% endfor %}
</div>
</div>
</section>
{% endif %}
{% endwith %}
{% endblock %}
+73
View File
@@ -0,0 +1,73 @@
{% extends "base.html" %}
{% load static %}
{% block title %}Products{% endblock %}
{% block meta_description %}Explore Tecvico's suite of medical imaging and radiomics software products.{% endblock %}
{% block content %}
<section class="page-hero" aria-labelledby="products-overview-heading">
<div class="page-hero-blobs" aria-hidden="true">
<div class="blob blob--1"></div>
<div class="blob blob--2"></div>
</div>
<div class="container">
<div class="page-hero-content">
<div class="section-badge">Software Suite</div>
<h1 class="page-hero-title" id="products-overview-heading">Our Products</h1>
<p class="page-hero-subtitle">Advanced tools for medical imaging research and radiomics analysis.</p>
</div>
</div>
</section>
<section class="section" aria-labelledby="products-list-heading">
<div class="container">
<h2 class="sr-only" id="products-list-heading">Product List</h2>
{% if main_products %}
<div class="products-overview-grid">
{% for product in main_products %}
<div class="product-overview-card glass-card fade-in">
{% if product.image %}
<div class="product-overview-image">
<img src="{{ product.image.url }}" alt="{{ product.name }}" loading="lazy" />
</div>
{% endif %}
<div class="product-overview-body">
<h2 class="product-overview-title">{{ product.name }}</h2>
<p class="product-overview-short">{{ product.short_description }}</p>
<p class="product-overview-desc">{{ product.description }}</p>
<a href="{{ product.get_absolute_url }}" class="btn-primary">Explore {{ product.name }}</a>
</div>
{% with subs=product.sub_products.all %}
{% if subs %}
<div class="product-overview-subs">
<h3 class="product-overview-subs-title">Modules</h3>
<ul class="product-overview-subs-list" role="list">
{% for sub in subs %}
{% if sub.is_active %}
<li>
<a href="{{ sub.get_absolute_url }}" class="sub-link-chip">
{{ sub.name }}
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" aria-hidden="true">
<path d="M2.5 6H9.5M9.5 6L7 3.5M9.5 6L7 8.5" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
</a>
</li>
{% endif %}
{% endfor %}
</ul>
</div>
{% endif %}
{% endwith %}
</div>
{% endfor %}
</div>
{% else %}
<div class="empty-state-block glass-card">
<p>No products available at this time. Check back soon.</p>
</div>
{% endif %}
</div>
</section>
{% endblock %}
+111
View File
@@ -0,0 +1,111 @@
{% extends "base.html" %}
{% load static %}
{% block title %}{{ sub_product.name }} — {{ main_product.name }}{% endblock %}
{% block meta_description %}{{ sub_product.short_description }}{% endblock %}
{% block content %}
<section class="page-hero" aria-labelledby="sub-product-heading">
<div class="page-hero-blobs" aria-hidden="true">
<div class="blob blob--1"></div>
<div class="blob blob--2"></div>
</div>
<div class="container">
<nav class="breadcrumb" aria-label="Breadcrumb">
<ol class="breadcrumb-list" role="list">
<li><a href="{% url 'pages:home' %}">Home</a></li>
<li aria-hidden="true" class="breadcrumb-sep"></li>
<li><a href="{% url 'products:overview' %}">Products</a></li>
<li aria-hidden="true" class="breadcrumb-sep"></li>
<li><a href="{{ main_product.get_absolute_url }}">{{ main_product.name }}</a></li>
<li aria-hidden="true" class="breadcrumb-sep"></li>
<li aria-current="page">{{ sub_product.name }}</li>
</ol>
</nav>
<div class="page-hero-content">
<div class="section-badge">{{ main_product.name }}</div>
<h1 class="page-hero-title" id="sub-product-heading">{{ sub_product.name }}</h1>
<p class="page-hero-subtitle">{{ sub_product.short_description }}</p>
</div>
</div>
</section>
<div class="section sub-product-layout">
<div class="container">
<div class="sub-product-grid">
<main class="sub-product-main">
{% if sub_product.image %}
<div class="sub-product-image glass-card fade-in">
<img src="{{ sub_product.image.url }}" alt="{{ sub_product.name }}" loading="lazy" />
</div>
{% endif %}
<div class="sub-product-desc glass-card fade-in">
<h2>About {{ sub_product.name }}</h2>
<p>{{ sub_product.description }}</p>
</div>
{% if articles %}
<section aria-labelledby="articles-heading">
<h2 class="articles-section-title" id="articles-heading">Articles</h2>
<div class="articles-list">
{% for article in articles %}
<article class="article-card glass-card fade-in" aria-labelledby="article-{{ article.pk }}-title">
<h3 class="article-title" id="article-{{ article.pk }}-title">{{ article.title }}</h3>
<p class="article-description">{{ article.description }}</p>
{% if article.sections.all %}
<div class="article-sections">
<dl class="article-sections-list">
{% for section in article.sections.all %}
<div class="article-section-item">
<dt class="section-key">{{ section.title }}</dt>
<dd class="section-value">{{ section.value }}</dd>
</div>
{% endfor %}
</dl>
</div>
{% endif %}
</article>
{% endfor %}
</div>
</section>
{% endif %}
</main>
<aside class="sub-product-sidebar" aria-label="Related modules">
<div class="sidebar-sticky">
<div class="sidebar-section glass-card">
<h3 class="sidebar-title">
<a href="{{ main_product.get_absolute_url }}">{{ main_product.name }}</a> Modules
</h3>
{% if siblings %}
<ul class="sidebar-list" role="list">
{% for sibling in siblings %}
<li>
<a href="{{ sibling.get_absolute_url }}" class="sidebar-link">
<span class="sidebar-dot" aria-hidden="true"></span>
{{ sibling.name }}
</a>
</li>
{% endfor %}
</ul>
{% else %}
<p class="sidebar-empty">No other modules in this product.</p>
{% endif %}
</div>
<a href="{{ main_product.get_absolute_url }}" class="btn-ghost sidebar-back-btn">
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true">
<path d="M10 3L5 8L10 13" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
Back to {{ main_product.name }}
</a>
</div>
</aside>
</div>
</div>
</div>
{% endblock %}